Ejemplo n.º 1
0
        private void CloseClientSocket(SocketAsyncEventArgs workerEventArgs)
        {
            var token = (DataHoldingUserToken <T>)workerEventArgs.UserToken;

            // --- Logging / Debugging
            _trace.ClosingConnection(_settings.CustomState, token, workerEventArgs.GetRemoteIpEndPoint(), token.CloseAfterSend, token.ClosedByClient, token.CloseReason);
            // ---

            _watchDog.RemoveWatch(workerEventArgs);

            // do a shutdown before you close the socket
            try
            {
                workerEventArgs.AcceptSocket.Shutdown(SocketShutdown.Both);
            }
            // throws if socket was already closed
            catch { }

            //This method closes the socket and releases all resources, both
            //managed and unmanaged. It internally calls Dispose.
            workerEventArgs.AcceptSocket.Close();
            token.Reset();

            _workerPool.Push(workerEventArgs);

            //Release Semaphore so that its connection counter will be decremented.
            //This must be done AFTER putting the SocketAsyncEventArg back into the pool,
            //or you can run into problems.
            _maxConnectionsEnforcer.Release();
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Setup connection to use a SocketAsyncEventArgs setup to send/Receive
        /// </summary>
        /// <param name="acceptEventArgs"></param>
        private void ProcessAccept(SocketAsyncEventArgs acceptEventArgs)
        {
            IdentityUserToken token = (IdentityUserToken)acceptEventArgs.UserToken;

            token.LastTalked = ServerDiagnostics.Instance.Now;

            // Handle failure to accept connection
            if (acceptEventArgs.SocketError != SocketError.Success)
            {
                StartAccept();

                HandleBadAccept(acceptEventArgs, acceptEventArgs.SocketError);

                return;
            }

            _trace.HandleAccept(_settings.CustomState, token, acceptEventArgs.GetRemoteIpEndPoint());

            // Begin listening for more connections
            StartAccept();

            var workerEventArgs = GetWorkerFromAcceptEventArgs(acceptEventArgs);

            _watchDog.AddWatch(workerEventArgs);

            StartReceive(workerEventArgs);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Begin sending data
        /// </summary>
        /// <param name="workerEventArgs"></param>
        private void StartSend(SocketAsyncEventArgs workerEventArgs)
        {
            DataHoldingUserToken <T> token = (DataHoldingUserToken <T>)workerEventArgs.UserToken;

            if (token.WriteDataBytesRemaining <= _settings.IoBufferSize)
            {
                // Whole remaining message will fit in buffer.
                workerEventArgs.SetBuffer(token.WriteBufferOffset, token.WriteDataBytesRemaining);
                Buffer.BlockCopy(token.WriteData, token.WriteDataBytesSent, workerEventArgs.Buffer, token.WriteBufferOffset, token.WriteDataBytesRemaining);

                // --- Logging / Debugging
                _trace.Sending(_settings.CustomState, token, workerEventArgs.GetRemoteIpEndPoint(), workerEventArgs.Buffer, token.WriteBufferOffset, token.WriteDataBytesRemaining);
                // ---
            }
            else
            {
                // Message to big to all go in buffer.

                workerEventArgs.SetBuffer(token.WriteBufferOffset, _settings.IoBufferSize);
                Buffer.BlockCopy(token.WriteData, token.WriteDataBytesSent, workerEventArgs.Buffer, token.WriteBufferOffset, _settings.IoBufferSize);

                // We update the token.WriteDataBytesSent once the Sending has been confirmed.

                // --- Logging / Debugging
                _trace.Sending(_settings.CustomState, token, workerEventArgs.GetRemoteIpEndPoint(), workerEventArgs.Buffer, token.WriteBufferOffset, _settings.IoBufferSize);
                // ---
            }


            bool runningAsync = workerEventArgs.AcceptSocket.SendAsync(workerEventArgs);

            if (!runningAsync)
            {
                ProcessSend(workerEventArgs);
            }
        }
Ejemplo n.º 4
0
        private void ProcessSend(SocketAsyncEventArgs workerEventArgs)
        {
            DataHoldingUserToken <T> token = (DataHoldingUserToken <T>)workerEventArgs.UserToken;

            token.WriteDataBytesSent += workerEventArgs.BytesTransferred;

            // --- Logging / Debugging
            _trace.Sent(_settings.CustomState, token, workerEventArgs.GetRemoteIpEndPoint(), workerEventArgs.BytesTransferred);
            // ---

            if (workerEventArgs.SocketError != SocketError.Success)
            {
                token.Reset();
                CloseClientSocket(workerEventArgs);

                return;
            }

            if (token.WriteDataBytesRemaining > 0)
            {
                // If some of the bytes in the message have NOT been sent,
                // then we will need to post another send operation
                StartSend(workerEventArgs);
            }
            else
            {
                if (token.CloseAfterSend)
                {
                    CloseClientSocket(workerEventArgs);
                }
                else
                {
                    StartReceive(workerEventArgs);
                }
            }
        }
Ejemplo n.º 5
0
        private void ProcessReceive(SocketAsyncEventArgs workerEventArgs)
        {
            var token = (DataHoldingUserToken <T>)workerEventArgs.UserToken;

            token.ReceivedBytes += workerEventArgs.BytesTransferred;
            token.LastTalked     = ServerDiagnostics.Instance.Now;

            // Check the socket is still good
            bool closeSocket =
                workerEventArgs.BytesTransferred == 0 ||                 // Client has closed the connection (Normal)
                workerEventArgs.SocketError != SocketError.Success ||    // Something has gone wrong. (Bad)
                token.ReceivedBytes > token.BufferSize;                  // Recieved more data then we can handle (Bad)

            // if not close the socket
            if (closeSocket)
            {
                if (token.ReceivedBytes > token.BufferSize && workerEventArgs.SocketError == SocketError.Success)
                {
                    _trace.ReceivedGreaterThanBuffer(_settings.CustomState, token, workerEventArgs.GetRemoteIpEndPoint(), workerEventArgs.Buffer, token.ReceiveBufferOffset, token.ReceivedBytes);
                }

                //token.Reset();
                token.ClosedByClient = workerEventArgs.BytesTransferred == 0;
                token.CloseReason    = workerEventArgs.SocketError;
                CloseClientSocket(workerEventArgs);

                return;
            }

            //Create a clone of the endpoint, as having a task might mean accessing the socket details after the endpoint is no longer valid.
            var        currentEndpoint = workerEventArgs.GetRemoteIpEndPoint();
            IPEndPoint ipEndPoint      = new IPEndPoint(currentEndpoint.Address, currentEndpoint.Port);

            // --- Logging / Debugging
            _trace.Received(_settings.CustomState, token, ipEndPoint, workerEventArgs.Buffer, token.ReceiveBufferOffset, token.ReceivedBytes);
            // ---

            // Check if we have a full message
            bool incomingMessageReady =
                _messageHandler.IsMessageComplete(workerEventArgs.Buffer, token.ReceiveBufferOffset, token.ReceivedBytes, workerEventArgs.BytesTransferred, token.SocketStateData);

            if (incomingMessageReady)
            {
                // If so handle it, and send a response
                // if we have one

                // --- Logging / Debugging
                _trace.QueuedTask(_settings.CustomState, token);
                // ---

                var requestStartTime = DateTime.Now;

                _taskManager.StartNew(state =>
                {
                    SocketListenerState s = (SocketListenerState)state;
                    try
                    {
                        // --- Logging / Debugging
                        _trace.StartingTask(_settings.CustomState, token, requestStartTime);
                        // ---

                        if ((DateTime.Now - requestStartTime).TotalSeconds > _settings.MaxTaskDelay)
                        {
                            _trace.ExpiredTask(_settings.CustomState, token);
                            CloseClientSocket(workerEventArgs);

                            return;
                        }

                        var response = _messageHandler.HandleMessage(s.EndPoint, workerEventArgs.Buffer, token.ReceiveBufferOffset, token.ReceivedBytes, _settings.CustomState, token.SocketStateData);
                        token.Reset();
                        token.WriteData      = response.ToSend;
                        token.CloseAfterSend = response.DisconnectOnceDone;

                        if (token.WriteData != null)
                        {
                            StartSend(workerEventArgs);
                        }
                        else if (response.DisconnectOnceDone)
                        {
                            CloseClientSocket(workerEventArgs);
                        }
                        else
                        {
                            StartReceive(workerEventArgs);
                        }

                        // --- Logging / Debugging
                        _trace.CompletedTask(_settings.CustomState, token);
                        // ---
                    }
                    catch (Exception e)
                    {
                        // Task failed...
                        _trace.FailedTask(_settings.CustomState, token, e);
                        CloseClientSocket(workerEventArgs);
                    }
                }, new SocketListenerState {
                    EndPoint = ipEndPoint
                });
            }
            else
            {
                // otherwise wait for more data to be recieved
                StartReceive(workerEventArgs);
            }
        }
Ejemplo n.º 6
0
        private void HandleBadAccept(SocketAsyncEventArgs acceptEventArgs, SocketError error)
        {
            // --- Logging / Debugging
            _trace.HandleBadAccept(_settings.CustomState, (IdentityUserToken)acceptEventArgs.UserToken, acceptEventArgs.GetRemoteIpEndPoint(), error);
            // ---

            acceptEventArgs.AcceptSocket.Close();
            acceptEventArgs.AcceptSocket = null;
            _acceptPool.Push(acceptEventArgs);
        }