private void BeginAccept(SocketAsyncEventArgs args) { LogProvider.Log("checking arguments", "TCPSocket.BeginAccept", LogLevel.Verbose); if (args == null) { args = _saeas.TakeNext(); args.UserToken = new UserDataToken(args.RemoteEndPoint); args.Completed += SocketAccept_Completed; _connectedSockets.Add(args); } try { // Accept a connection and see if the event completed synchronously or not LogProvider.Log("attempting to accept a client asynchronously", "TCPSocket.BeginAccept", LogLevel.Verbose); if (!_socket.AcceptAsync(args)) { // We need to process the accept manually LogProvider.Log("but completed synchronously", "TCPSocket.BeginAccept", LogLevel.Verbose); ClientAccepted(args); } } catch { // we should only jump here when we disconnect all the clients. LogProvider.Log("exception thrown", "TCPSocket.BeginAccept", LogLevel.Verbose); } }
private void Receive() { SocketAsyncEventArgs args = _saeas.TakeNext(); byte[] buff = _buffers.TakeNext(); args.SetBuffer(buff, 0, buff.Length); args.Completed += PacketReceived; args.RemoteEndPoint = new IPEndPoint(BindingAddress, Port); try { if (!_socket.ReceiveMessageFromAsync(args)) { OnPacketReceived(args); } } catch (Exception ex) { // we should only jump here when we disconnect all the clients. Console.WriteLine(ex.Message); } }
private void BeginReceive(SocketAsyncEventArgs e) { // see if we can prevent an operation exception LogProvider.Log("starting receive", "TCPSocket.BeginReceive", LogLevel.Verbose); if (((UserDataToken)e.UserToken).PendingReceiveOperation) { return; } byte[] buffer; // pattern to avoid duplicating events e.Completed -= SocketAccept_Completed; e.Completed -= SocketData_Completed; e.Completed += SocketData_Completed; LogProvider.Log("event handlers re-assigned", "TCPSocket.BeginReceive", LogLevel.Verbose); // set the buffer before we start if (e.Buffer != null) { buffer = e.Buffer; Array.Clear(buffer, 0, buffer.Length); } else { buffer = _buffers.TakeNext(); } LogProvider.Log("buffer cleared/created", "TCPSocket.BeginReceive", LogLevel.Verbose); // reset the buffer e.SetBuffer(buffer, 0, buffer.Length); ((UserDataToken)e.UserToken).PendingReceiveOperation = true; LogProvider.Log("pending operation set", "TCPSocket.BeginReceive", LogLevel.Verbose); // Accept some data and see if the event completed synchronously or not LogProvider.Log("attempting to receive data asynchronously", "TCPSocket.BeginReceive", LogLevel.Verbose); if (!Extensions.Coalesce(e.AcceptSocket, e.ConnectSocket, _socket).ReceiveAsync(e)) { LogProvider.Log("but completed synchronously", "TCPSocket.BeginReceive", LogLevel.Verbose); // We need to process the data manually DataReceived(e); } }
private void OnPacketReceived(SocketAsyncEventArgs e) { // Start a new Receive operation straight away Receive(); if (e.ReceiveMessageFromPacketInfo.Address == null) { // this needs a permenant fix Console.WriteLine("Null address, exiting..."); return; } // Now process the packet that we have already if (e.BytesTransferred <= MessagePrefixLength) { // Error condition, empty packet LogProvider.Log(String.Format("Empty packet received from {0}. Discarding packet.", e.ReceiveMessageFromPacketInfo.Address), "UDPSocket.OnPacketReceived", LogLevel.Minimal); ReleaseArgs(e); return; } // Make sure that we aren't the source of the message. if (e.ReceiveMessageFromPacketInfo.Address.Equals(((IPEndPoint)_socket.LocalEndPoint).Address)) { LogProvider.Log("Received packet from this node. Disregarding.", "UDPSocket.OnPacketReceived", LogLevel.Verbose); ReleaseArgs(e); return; } // Get the message length from the beginning of the packet. byte[] arrPrefix = _tempBuffers.TakeNext(); Buffer.BlockCopy(e.Buffer, e.Offset, arrPrefix, 0, MessagePrefixLength); Int32 messageLength = BitConverter.ToInt32(arrPrefix, 0); // clear and return the buffer asap Array.Clear(arrPrefix, 0, MessagePrefixLength); _tempBuffers.Insert(arrPrefix); // the number of bytes remaining to store Int32 bytesToProcess = e.BytesTransferred - MessagePrefixLength; if (bytesToProcess < messageLength) { LogProvider.Log(String.Format("Missing data from {0}. Discarding packet.", e.ReceiveMessageFromPacketInfo.Address), "UDPSocket.OnPacketReceived", LogLevel.Minimal); ReleaseArgs(e); return; } // Create a data buffer byte[] data = _buffers.TakeNext(); // new byte[messageLength]; // Copy the remaining data to the data buffer on the user token Buffer.BlockCopy(e.Buffer, e.Offset + MessagePrefixLength, data, 0, messageLength); // Thread safe way of triggering the event var evnt = OnDataReceived; if (evnt != null) { evnt(e, new SocketDataEventArgs(data, _type, e.ReceiveMessageFromPacketInfo.Address)); _buffers.Insert(data); } // Data is safely stored, so unhook the event and return the SocketAsyncEventArgs back to the pool ReleaseArgs(e); }