private async Task Accept()
        {
            try
            {
                while (IsListening)
                {
                    var saea = _acceptSaeaPool.Take();

                    var socketError = await _listener.AcceptAsync(saea);

                    if (socketError == SocketError.Success)
                    {
                        var acceptedSocket = saea.Saea.AcceptSocket;
                        Task.Run(async() =>
                        {
                            await Process(acceptedSocket);
                        })
                        .Forget();
                    }
                    else
                    {
                        _log.ErrorFormat("Error occurred when accept incoming socket [{0}].", socketError);
                    }

                    _acceptSaeaPool.Return(saea);
                }
            }
            catch (Exception ex) when(!ShouldThrow(ex))
            {
            }
            catch (Exception ex)
            {
                _log.Error(ex.Message, ex);
            }
        }
Ejemplo n.º 2
0
        public async Task Connect()
        {
            int origin = Interlocked.Exchange(ref _state, _connecting);

            if (!(origin == _none || origin == _closed))
            {
                await Close(false);

                throw new InvalidOperationException("This tcp socket client is in invalid state when connecting.");
            }

            try
            {
                Clean();

                _socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
                SetSocketOptions();

                if (_localEndPoint != null)
                {
                    _socket.Bind(_localEndPoint);
                }

                var saea = _saeaPool.Take();
                saea.Saea.RemoteEndPoint = _remoteEndPoint;

                var socketError = await _socket.ConnectAsync(saea);

                if (socketError != SocketError.Success)
                {
                    throw new SocketException((int)socketError);
                }

                if (_receiveBuffer == default(ArraySegment <byte>))
                {
                    _receiveBuffer = _configuration.BufferManager.BorrowBuffer();
                }
                _receiveBufferOffset = 0;

                if (Interlocked.CompareExchange(ref _state, _connected, _connecting) != _connecting)
                {
                    await Close(false);

                    throw new InvalidOperationException("This tcp socket client is in invalid state when connected.");
                }

                Loger.DebugFormat("Connected to server [{0}] with dispatcher [{1}] on [{2}].",
                                  this.RemoteEndPoint,
                                  _dispatcher.GetType().Name,
                                  DateTime.UtcNow.ToString(@"yyyy-MM-dd HH:mm:ss.fffffff"));
                bool isErrorOccurredInUserSide = false;
                try
                {
                    await _dispatcher.OnServerConnected(this);
                }
                catch (Exception ex)
                {
                    isErrorOccurredInUserSide = true;
                    HandleUserSideError(ex);
                }

                if (!isErrorOccurredInUserSide)
                {
                    Task.Factory.StartNew(async() =>
                    {
                        await Process();
                    },
                                          TaskCreationOptions.LongRunning)
                    .Forget();
                }
                else
                {
                    await Close();
                }
            }
            catch (Exception ex)
            {
                Loger.Error(ex.Message, ex);
                throw;
            }
        }
Ejemplo n.º 3
0
        private async Task Process()
        {
            try
            {
                int    frameLength;
                byte[] payload;
                int    payloadOffset;
                int    payloadCount;
                int    consumedLength = 0;

                var saea = _saeaPool.Take();
                saea.Saea.SetBuffer(_receiveBuffer.Array, _receiveBuffer.Offset + _receiveBufferOffset, _receiveBuffer.Count - _receiveBufferOffset);

                while (State == TcpSocketConnectionState.Connected)
                {
                    saea.Saea.SetBuffer(_receiveBuffer.Array, _receiveBuffer.Offset + _receiveBufferOffset, _receiveBuffer.Count - _receiveBufferOffset);

                    var socketError = await _socket.ReceiveAsync(saea);

                    if (socketError != SocketError.Success)
                    {
                        break;
                    }

                    var receiveCount = saea.Saea.BytesTransferred;
                    if (receiveCount == 0)
                    {
                        break;
                    }

                    SegmentBufferDeflector.ReplaceBuffer(_bufferManager, ref _receiveBuffer, ref _receiveBufferOffset, receiveCount);
                    consumedLength = 0;

                    while (true)
                    {
                        frameLength   = 0;
                        payload       = null;
                        payloadOffset = 0;
                        payloadCount  = 0;

                        if (_configuration.FrameBuilder.Decoder.TryDecodeFrame(
                                _receiveBuffer.Array,
                                _receiveBuffer.Offset + consumedLength,
                                _receiveBufferOffset - consumedLength,
                                out frameLength, out payload, out payloadOffset, out payloadCount))
                        {
                            try
                            {
                                await _dispatcher.OnSessionDataReceived(this, payload, payloadOffset, payloadCount);
                            }
                            catch (Exception ex)
                            {
                                HandleUserSideError(ex);
                            }
                            finally
                            {
                                consumedLength += frameLength;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }

                    try
                    {
                        SegmentBufferDeflector.ShiftBuffer(_bufferManager, consumedLength, ref _receiveBuffer, ref _receiveBufferOffset);
                    }
                    catch (ArgumentOutOfRangeException) { }
                }
            }
            catch (Exception ex) when(!ShouldThrow(ex))
            {
            }
            finally
            {
                await Close();
            }
        }
Ejemplo n.º 4
0
        public async Task Connect()
        {
            int origin = Interlocked.CompareExchange(ref _state, _connecting, _none);

            if (origin == _disposed)
            {
                throw new ObjectDisposedException(GetType().FullName);
            }
            else if (origin != _none)
            {
                throw new InvalidOperationException("This tcp socket client has already connected to server.");
            }

            try
            {
                _socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
                if (_localEndPoint != null)
                {
                    _socket.Bind(_localEndPoint);
                }

                var saea = _saeaPool.Take();
                saea.Saea.RemoteEndPoint = _remoteEndPoint;

                var socketError = await _socket.ConnectAsync(saea);

                if (socketError != SocketError.Success)
                {
                    throw new SocketException((int)socketError);
                }

                ConfigureSocket();

                _receiveBuffer       = _bufferManager.BorrowBuffer();
                _receiveBufferOffset = 0;

                if (Interlocked.CompareExchange(ref _state, _connected, _connecting) != _connecting)
                {
                    throw new ObjectDisposedException(GetType().FullName);
                }

                _log.DebugFormat("Connected to server [{0}] with dispatcher [{1}] on [{2}].",
                                 this.RemoteEndPoint,
                                 _dispatcher.GetType().Name,
                                 DateTime.UtcNow.ToString(@"yyyy-MM-dd HH:mm:ss.fffffff"));
                bool isErrorOccurredInUserSide = false;
                try
                {
                    await _dispatcher.OnServerConnected(this);
                }
                catch (Exception ex)
                {
                    isErrorOccurredInUserSide = true;
                    HandleUserSideError(ex);
                }

                if (!isErrorOccurredInUserSide)
                {
                    Task.Run(async() =>
                    {
                        await Process();
                    })
                    .Forget();
                }
                else
                {
                    await Close();
                }
            }
            catch (ObjectDisposedException) { }
            catch (Exception ex)
                when(ex is TimeoutException)
                {
                    _log.Error(ex.Message, ex);
                    await Close();
                }
        }
Ejemplo n.º 5
0
        private async Task Process()
        {
            var saea = _saeaPool.Take();

            try
            {
                int    frameLength;
                byte[] payload;
                int    payloadOffset;
                int    payloadCount;
                int    consumedLength = 0;

                saea.Saea.SetBuffer(_receiveBuffer.Array, _receiveBuffer.Offset + _receiveBufferOffset, _receiveBuffer.Count - _receiveBufferOffset);

                while (State == TcpSocketConnectionState.Connected)
                {
                    saea.Saea.SetBuffer(_receiveBuffer.Array, _receiveBuffer.Offset + _receiveBufferOffset, _receiveBuffer.Count - _receiveBufferOffset);

                    var socketError = await _socket.ReceiveAsync(saea);

                    if (socketError != SocketError.Success)
                    {
                        break;
                    }

                    var receiveCount = saea.Saea.BytesTransferred;
                    if (receiveCount == 0)
                    {
                        break;
                    }

                    SegmentBufferDeflector.ReplaceBuffer(_bufferManager, ref _receiveBuffer, ref _receiveBufferOffset, receiveCount);
                    consumedLength = 0;

                    while (true)
                    {
                        frameLength   = 0;
                        payload       = null;
                        payloadOffset = 0;
                        payloadCount  = 0;

                        if (_configuration.FrameBuilder.Decoder.TryDecodeFrame(
                                _receiveBuffer.Array,
                                _receiveBuffer.Offset + consumedLength,
                                _receiveBufferOffset - consumedLength,
                                out frameLength, out payload, out payloadOffset, out payloadCount))
                        {
                            try
                            {
                                await _dispatcher.OnSessionDataReceived(this, payload, payloadOffset, payloadCount);
                            }
                            catch (Exception ex) // catch all exceptions from out-side
                            {
                                await HandleUserSideError(ex);
                            }
                            finally
                            {
                                consumedLength += frameLength;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }

                    if (_receiveBuffer != null && _receiveBuffer.Array != null)
                    {
                        SegmentBufferDeflector.ShiftBuffer(_bufferManager, consumedLength, ref _receiveBuffer, ref _receiveBufferOffset);
                    }
                }
            }
            catch (Exception ex)
            {
                await HandleReceiveOperationException(ex);
            }
            finally
            {
                await Close(true); // read async buffer returned, remote closed

                _saeaPool.Return(saea);
            }
        }
Ejemplo n.º 6
0
        private async Task Process()
        {
            try
            {
                int    frameLength;
                byte[] payload;
                int    payloadOffset;
                int    payloadCount;

                var saea = _saeaPool.Take();
                saea.Saea.SetBuffer(_receiveBuffer, 0, _receiveBuffer.Length);

                while (State == TcpSocketConnectionState.Connected)
                {
                    saea.Saea.SetBuffer(0, _receiveBuffer.Length);

                    var socketError = await _socket.ReceiveAsync(saea);

                    if (socketError != SocketError.Success)
                    {
                        break;
                    }

                    var receiveCount = saea.Saea.BytesTransferred;
                    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();
            }
        }