private void SendAsyncStream_Completed(object sender, SocketAsyncEventArgs e)
        {
            e.Completed -= SendAsyncStream_Completed;

            byte[] buffer;
            int    bytesRead = 0;
            TcpConnectionAsyncEventArgs userToken = (TcpConnectionAsyncEventArgs)e.UserToken;

            if (!TryStopTimeout(userToken))
            {
                return;
            }

            _bytesSentTotal += (ulong)e.BytesTransferred;
            if (OnProgress != null)
            {
                OnProgress(this, DirectionType.Upload, e.BytesTransferred);
            }

            bytesRead = GetBytesFromStream(userToken.Stream, out buffer, SendBufferSettings.Size);

            if (bytesRead <= 0)
            {
                if (userToken.AsyncCallback != null)
                {
                    userToken.BytesTransferred = e.BytesTransferred;
                    userToken.AsyncCallback(this, userToken);
                }
                return;
            }

            e.SetBuffer(buffer, 0, bytesRead);
            e.UserToken = new TcpConnectionAsyncEventArgs(new Timeout(SendBufferSettings.Timeout, SendAsync_Timeout), userToken.Stream);

            lock (_socket)
            {
                try
                {
                    Logger.Network.Debug("Socket ID: " + _socket.GetHashCode().ToString() + "\r\nSending Packet:\r\n" + System.Text.Encoding.UTF8.GetString(buffer, 0, bytesRead));
                    if (!_socket.SendAsync(e))
                    {
                        Logger.Network.Debug("Socket ID: " + _socket.GetHashCode().ToString() + "\r\nSendAsyncStream_Completed completed synchronously.");
                        SendAsyncStream_Completed(null, e);
                    }
                }
                catch (Exception ex)
                {
                    Logger.Network.Error("Socket ID: " + _socket.GetHashCode().ToString() + "\r\nAn exception occurred while sending on socket.", ex);
                    if (OnError != null)
                    {
                        OnError(this, "Exception sending on socket.", ex);
                    }
                    else
                    {
                        throw;
                    }
                }
            }
        }
        private void ReceiveAsync_Completed(object sender, SocketAsyncEventArgs e)
        {
            TcpConnectionAsyncEventArgs userToken = (TcpConnectionAsyncEventArgs)e.UserToken;

            if (!TryStopTimeout(userToken))
            {
                return;
            }

            _bytesReceivedTotal += (ulong)e.BytesTransferred;

            Logger.Network.Debug("Socket ID: " + _socket.GetHashCode().ToString() + "\r\nReceiving Packet of length " + e.BytesTransferred.ToString() + ":\r\n" + System.Text.Encoding.UTF8.GetString(e.Buffer, e.Offset, e.BytesTransferred));

            try
            {
                if (OnProgress != null)
                {
                    OnProgress(this, DirectionType.Download, e.BytesTransferred);
                }
            }
            catch (Exception ex)
            {
                Logger.Network.Error("Socket ID: " + _socket.GetHashCode().ToString() + "\r\nTcpConnection ID: " + this.GetHashCode().ToString() + "\r\nAn error occurred while reporting progress to higher level code.\r\nMessage: " + ex.Message, ex);
            }

            if (userToken.AsyncCallback != null)
            {
                userToken.BytesTransferred = e.BytesTransferred;
                userToken.Buffer           = e.Buffer;
                userToken.Length           = e.Count;
                try
                {
                    userToken.AsyncCallback(this, userToken);
                }
                catch (Exception ex)
                {
                    Logger.Network.Error("Socket ID: " + _socket.GetHashCode().ToString() + "\r\nTcpConnection ID: " + this.GetHashCode().ToString() + "\r\nAn error occurred while reporting progress to higher level code.\r\nMessage: " + ex.Message, ex);
                }
            }
        }
        private void SendAsync_Completed(object sender, SocketAsyncEventArgs e)
        {
            e.Completed -= SendAsyncStream_Completed;
            TcpConnectionAsyncEventArgs userToken = (TcpConnectionAsyncEventArgs)e.UserToken;

            if (!TryStopTimeout(userToken))
            {
                return;
            }

            _bytesSentTotal += (ulong)e.BytesTransferred;
            if (OnProgress != null)
            {
                OnProgress(this, DirectionType.Upload, e.BytesTransferred);
            }

            if (userToken.AsyncCallback != null)
            {
                userToken.BytesTransferred = e.BytesTransferred;
                userToken.AsyncCallback(this, userToken);
            }
        }