private void ClientAccepted(SocketAsyncEventArgs e) { LogProvider.Log("client has been accepted, checking for socket error", "TCPSocket.ClientAccepted", LogLevel.Verbose); if (e.SocketError != SocketError.Success) { // Potential bad socket LogProvider.Log("potential bad socket", "TCPSocket.ClientAccepted", LogLevel.Verbose); BeginAccept(e); return; } // make sure that the token has some data in it var token = (UserDataToken)e.UserToken; if (token == null || token.Endpoint == null) { token = new UserDataToken(Extensions.Coalesce(e.AcceptSocket, e.ConnectSocket, _socket).RemoteEndPoint); } LogProvider.Log("token parsing complete", "TCPSocket.ClientAccepted", LogLevel.Verbose); // Increment the amount of connected clients lock (_locker) { Interlocked.Increment(ref _connectedClients); LogProvider.Log("Connected Clients = " + _connectedClients, "TCPSocket.ClientAccepted", LogLevel.Minimal); } LogProvider.Log("beginning new accept operation", "TCPSocket.ClientAccepted", LogLevel.Verbose); // Now we have the connection, we can start a new accept operation BeginAccept(null); // re-assign the completed event handler for the SocketAsyncEventArgs e.UserToken = token; LogProvider.Log("token re-assigned", "TCPSocket.ClientAccepted", LogLevel.Verbose); // Add the client to know clients if (!_ipAddresses.ContainsKey(token.Endpoint.Address)) { LogProvider.Log("ip address added to known addresses", "TCPSocket.ClientAccepted", LogLevel.Verbose); _ipAddresses.Add(token.Endpoint.Address, e); } LogProvider.Log("starting the receive operation", "TCPSocket.ClientAccepted", LogLevel.Verbose); // Start receiving the data BeginReceive(e); }
private void DataReceived(SocketAsyncEventArgs e) { LogProvider.Log("start", "TCPSocket.DataReceived", LogLevel.Verbose); if (e.SocketError != SocketError.Success || (e.BytesTransferred == 0 && e.LastOperation != SocketAsyncOperation.Accept)) { // Close the connection, e.BytesTransferred == 0 indicates that the socket is being closed by the client, usually. Socket sock = Extensions.Coalesce(e.AcceptSocket, e.ConnectSocket); if (_ipAddresses.ContainsKey(((IPEndPoint)sock.RemoteEndPoint).Address)) { _ipAddresses.Remove(((IPEndPoint)sock.RemoteEndPoint).Address); } return; } UserDataToken userToken = (UserDataToken)e.UserToken; userToken.PendingReceiveOperation = false; LogProvider.Log("token parsed", "TCPSocket.DataReceived", LogLevel.Verbose); if (userToken == null || _stopProcessingPackets) { // The client is in the process of being disconnected return; } LogProvider.Log("checking for first packet", "TCPSocket.DataReceived", LogLevel.Verbose); bool isFirstMessage = (userToken.ProcessedBytes == 0); Int32 bytesToProcess = e.BytesTransferred; Int32 bytesToProcessOffset = 0; // handle the prefix if neccessary if (isFirstMessage) { LogProvider.Log("this is the first packet", "TCPSocket.DataReceived", LogLevel.Verbose); // Store the message prefix as raw bytes byte[] arrPrefix = new byte[MessagePrefixLength]; Buffer.BlockCopy(e.Buffer, 0, arrPrefix, 0, MessagePrefixLength); // Set the message length userToken.DataLength = BitConverter.ToInt32(arrPrefix, 0); LogProvider.Log("expected data length is " + userToken.DataLength, "TCPSocket.DataReceived", LogLevel.Verbose); // Remove the amount of bytes to process bytesToProcess -= MessagePrefixLength; bytesToProcessOffset = MessagePrefixLength; // Setup the data buffer to store the whole data userToken.DataBuffer = new byte[userToken.DataLength]; // If we just have the header of the message then start another receive operation if (bytesToProcess == 0) { BeginReceive(e); return; } } // Copy the remaining data to the data buffer on the user token Buffer.BlockCopy(e.Buffer, bytesToProcessOffset, userToken.DataBuffer, userToken.ProcessedBytes, bytesToProcess); LogProvider.Log("data copied to token buffer", "TCPSocket.DataReceived", LogLevel.Verbose); // Increment the ProcessedBytes so we can see whether or not we have the full message userToken.ProcessedBytes += bytesToProcess; if (userToken.ProcessedBytes == userToken.DataLength) { LogProvider.Log("all data received", "TCPSocket.DataReceived", LogLevel.Verbose); // Thread safe way of triggering the event var evnt = OnDataReceived; if (evnt != null) { LogProvider.Log("event fired", "TCPSocket.DataReceived", LogLevel.Verbose); evnt(e, new SocketDataEventArgs(userToken.DataBuffer, PacketType.TCP, userToken.Endpoint.Address)); } // reset the token for the next message userToken.Reset(); LogProvider.Log("token reset", "TCPSocket.DataReceived", LogLevel.Verbose); } // Start a new receive operation LogProvider.Log("starting another receive operation", "TCPSocket.DataReceived", LogLevel.Verbose); BeginReceive(e); }