private void ProcessReceive(SocketAsyncEventArgs sockAsyncArgs) { if (!_isRunning) { return; } long clientID = (long)sockAsyncArgs.UserToken; if (!_clients.TryGetValue(clientID, out ClientContext clientContext)) { return; } Socket sockClient = clientContext.ClientSocket; if (sockAsyncArgs.SocketError == SocketError.Success) { int recvCount = sockAsyncArgs.BytesTransferred; if (recvCount > 0) { RingQueue clientRingBuffer = clientContext.ReceiveBuffer; clientRingBuffer.Write(sockAsyncArgs.Buffer, sockAsyncArgs.Offset, recvCount); //speed limit if (clientContext.RecvSpeedController != null) { clientContext.RecvSpeedController.TryLimit(recvCount); } //try get a completed packet List <DataPacket> messageList = null; int endPos = 0; try { messageList = _packetSpliter.GetPackets(clientRingBuffer.Buffer, 0, clientRingBuffer.DataLength, clientID, out endPos); } catch (NotImplementedException) { clientRingBuffer.Clear(); } catch (Exception ex) { TcpRawMessageReceivedEventArgs rawMessage = new TcpRawMessageReceivedEventArgs() { Message = null, Error = ex, ClientID = clientID }; OnRawMessageReceived(rawMessage); } if (messageList != null) { try { clientRingBuffer.Remove(endPos); foreach (DataPacket messageSegment in messageList) { clientContext.RecvRawMessage.ClientID = (long)sockClient.Handle; clientContext.RecvRawMessage.MessageRawData = messageSegment.Data; clientContext.RecvRawMessage.Tag = messageSegment.Tag; TcpRawMessageReceivedEventArgs rawMessage = new TcpRawMessageReceivedEventArgs() { Message = clientContext.RecvRawMessage, ClientID = clientID }; OnRawMessageReceived(rawMessage); } } catch (InvalidPacketException) { //invalid data received , indicates the client has made a illegal connection, we should disconnect it. _logger?.Info("illegal connection detected"); if (_isRunning) { CloseClient(true, (long)sockClient.Handle); } return; } catch (Exception ex) { _logger?.Warn("an error has occurred during get packets", ex.Message); } } //in case of the socket is closed, the following statements may cause of exception, so we should use try catch try { if (!clientContext.ClientSocket.ReceiveAsync(sockAsyncArgs)) { ProcessReceive(sockAsyncArgs); } } catch { } } else { _logger?.Warn($"sockAsyncArgs got an error: {sockAsyncArgs.SocketError.ToString()}"); if (_isRunning) { CloseClient(true, clientID); } } } else { if (_isRunning) { CloseClient(true, clientID); } } }