예제 #1
0
        private async Task Process()
        {
            try
            {
                int    frameLength;
                byte[] payload;
                int    payloadOffset;
                int    payloadCount;

                while (State == TcpSocketConnectionState.Connected)
                {
                    int receiveCount = await _stream.ReadAsync(_receiveBuffer, 0, _receiveBuffer.Length);

                    if (receiveCount == 0)
                    {
                        break;
                    }

                    BufferDeflector.AppendBuffer(_bufferManager, ref _receiveBuffer, receiveCount, ref _sessionBuffer, ref _sessionBufferCount);

                    while (true)
                    {
                        if (_configuration.FrameBuilder.TryDecodeFrame(_sessionBuffer, _sessionBufferCount,
                                                                       out frameLength, out payload, out payloadOffset, out payloadCount))
                        {
                            try
                            {
                                await _dispatcher.OnSessionDataReceived(this, payload, payloadOffset, payloadCount);
                            }
                            catch (Exception ex)
                            {
                                HandleUserSideError(ex);
                            }
                            finally
                            {
                                BufferDeflector.ShiftBuffer(_bufferManager, frameLength, ref _sessionBuffer, ref _sessionBufferCount);
#if DEBUG
                                _log.DebugFormat("Session [{0}] buffer length [{1}].", this, _sessionBufferCount);
#endif
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                }
            }
            catch (Exception ex) when(!ShouldThrow(ex))
            {
            }
            finally
            {
                await Close();
            }
        }
예제 #2
0
        private void ReceiveBuffer(int receiveCount)
        {
            // TCP guarantees delivery of all packets in the correct order.
            // But there is no guarantee that one write operation on the sender-side will result in
            // one read event on the receiving side. One call of write(message) by the sender
            // can result in multiple messageReceived(session, message) events on the receiver;
            // and multiple calls of write(message) can lead to a single messageReceived event.
            // In a stream-based transport such as TCP/IP, received data is stored into a socket receive buffer.
            // Unfortunately, the buffer of a stream-based transport is not a queue of packets but a queue of bytes.
            // It means, even if you sent two messages as two independent packets,
            // an operating system will not treat them as two messages but as just a bunch of bytes.
            // Therefore, there is no guarantee that what you read is exactly what your remote peer wrote.
            // There are three common techniques for splitting the stream of bytes into messages:
            //   1. use fixed length messages
            //   2. use a fixed length header that indicates the length of the body
            //   3. using a delimiter; for example many text-based protocols append
            //      a newline (or CR LF pair) after every message.
            int frameLength;

            byte[] payload;
            int    payloadOffset;
            int    payloadCount;

            BufferDeflector.AppendBuffer(_bufferManager, ref _receiveBuffer, receiveCount, ref _sessionBuffer, ref _sessionBufferCount);

            while (true)
            {
                if (_configuration.FrameBuilder.TryDecodeFrame(_sessionBuffer, _sessionBufferCount,
                                                               out frameLength, out payload, out payloadOffset, out payloadCount))
                {
                    try
                    {
                        RaiseServerDataReceived(payload, payloadOffset, payloadCount);
                    }
                    catch (Exception ex)
                    {
                        HandleUserSideError(ex);
                    }
                    finally
                    {
                        BufferDeflector.ShiftBuffer(_bufferManager, frameLength, ref _sessionBuffer, ref _sessionBufferCount);
#if DEBUG
                        _log.DebugFormat("Session [{0}] buffer length [{1}].", this, _sessionBufferCount);
#endif
                    }
                }
                else
                {
                    break;
                }
            }
        }