コード例 #1
0
ファイル: TcpBase.cs プロジェクト: Stmen/SiS.Communcation
        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);
                }
            }
        }