Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        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);
        }