| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753 | 
							- using System;
 
- using System.IO;
 
- using System.Net;
 
- using System.Net.Security;
 
- using System.Net.Sockets;
 
- using System.Security.Cryptography.X509Certificates;
 
- using System.Threading;
 
- using Aitex.Core.RT.Log;
 
- using MECF.Framework.Common.Communications.Tcp.Buffer;
 
- using MECF.Framework.Common.Communications.Tcp.Socket.Client.APM.EventArgs;
 
- namespace MECF.Framework.Common.Communications.Tcp.Socket.Client.APM
 
- {
 
-     public class TcpSocketClient : IDisposable
 
-     {
 
-         #region Fields
 
- //        private static readonly ILogger _log = LoggerManager.GetLogger(Assembly.GetExecutingAssembly(), "Tcp");//. .Get<TcpSocketClient>();
 
-         private TcpClient _tcpClient;
 
-         private readonly TcpSocketClientConfiguration _configuration;
 
-         private readonly IPEndPoint _remoteEndPoint;
 
-         private readonly IPEndPoint _localEndPoint;
 
-         private Stream _stream;
 
-         private ArraySegment<byte> _receiveBuffer = default(ArraySegment<byte>);
 
-         private int _receiveBufferOffset = 0;
 
-         private int _state;
 
-         private const int _none = 0;
 
-         private const int _connecting = 1;
 
-         private const int _connected = 2;
 
-         private const int _closed = 5;
 
-         #endregion
 
-         #region Constructors
 
-         public TcpSocketClient(IPAddress remoteAddress, int remotePort, IPAddress localAddress, int localPort, TcpSocketClientConfiguration configuration = null)
 
-             : this(new IPEndPoint(remoteAddress, remotePort), new IPEndPoint(localAddress, localPort), configuration)
 
-         {
 
-         }
 
-         public TcpSocketClient(IPAddress remoteAddress, int remotePort, IPEndPoint localEP = null, TcpSocketClientConfiguration configuration = null)
 
-             : this(new IPEndPoint(remoteAddress, remotePort), localEP, configuration)
 
-         {
 
-         }
 
-         public TcpSocketClient(IPEndPoint remoteEP, TcpSocketClientConfiguration configuration = null)
 
-             : this(remoteEP, null, configuration)
 
-         {
 
-         }
 
-         public TcpSocketClient(IPEndPoint remoteEP, IPEndPoint localEP, TcpSocketClientConfiguration configuration = null)
 
-         {
 
-             if (remoteEP == null)
 
-                 throw new ArgumentNullException("remoteEP");
 
-             _remoteEndPoint = remoteEP;
 
-             _localEndPoint = localEP;
 
-             _configuration = configuration ?? new TcpSocketClientConfiguration();
 
-             if (_configuration.BufferManager == null)
 
-                 throw new InvalidProgramException("The buffer manager in configuration cannot be null.");
 
-             if (_configuration.FrameBuilder == null)
 
-                 throw new InvalidProgramException("The frame handler in configuration cannot be null.");
 
-         }
 
-         #endregion
 
-         #region Properties
 
-         public TimeSpan ConnectTimeout { get { return _configuration.ConnectTimeout; } }
 
-         private bool Connected { get { return _tcpClient != null && _tcpClient.Client.Connected; } }
 
-         public IPEndPoint RemoteEndPoint { get { return Connected ? (IPEndPoint)_tcpClient.Client.RemoteEndPoint : _remoteEndPoint; } }
 
-         public IPEndPoint LocalEndPoint { get { return Connected ? (IPEndPoint)_tcpClient.Client.LocalEndPoint : _localEndPoint; } }
 
-         public TcpSocketConnectionState State
 
-         {
 
-             get
 
-             {
 
-                 switch (_state)
 
-                 {
 
-                     case _none:
 
-                         return TcpSocketConnectionState.None;
 
-                     case _connecting:
 
-                         return TcpSocketConnectionState.Connecting;
 
-                     case _connected:
 
-                         return TcpSocketConnectionState.Connected;
 
-                     case _closed:
 
-                         return TcpSocketConnectionState.Closed;
 
-                     default:
 
-                         return TcpSocketConnectionState.Closed;
 
-                 }
 
-             }
 
-         }
 
-         public override string ToString()
 
-         {
 
-             return string.Format("RemoteEndPoint[{0}], LocalEndPoint[{1}]",
 
-                 this.RemoteEndPoint, this.LocalEndPoint);
 
-         }
 
-         /// <summary>
 
-         /// Checks the connection state
 
-         /// </summary>
 
-         /// <returns>True on connected. False on disconnected.</returns>
 
-         public bool IsConnected()
 
-         {
 
-             if (Connected)
 
-             {
 
-                 if ((_tcpClient.Client.Poll(0, SelectMode.SelectWrite)) && (!_tcpClient.Client.Poll(0, SelectMode.SelectError)))
 
-                 {
 
-                     byte[] buffer = new byte[1];
 
-                     if (_tcpClient.Client.Receive(buffer, SocketFlags.Peek) == 0)
 
-                     {
 
-                         return false;
 
-                     }
 
-                     else
 
-                     {
 
-                         return true;
 
-                     }
 
-                 }
 
-                 else
 
-                 {
 
-                     return false;
 
-                 }
 
-             }
 
-             else
 
-             {
 
-                 return false;
 
-             }
 
-         }
 
-         #endregion
 
-         #region Connect
 
-         public void Connect()
 
-         {
 
-             int origin = Interlocked.Exchange(ref _state, _connecting);
 
-             if (!(origin == _none || origin == _closed))
 
-             {
 
-                 Close(false);
 
-                 throw new InvalidOperationException("This tcp socket client is in invalid state when connecting.");
 
-             }
 
-             Clean();
 
-             _tcpClient = _localEndPoint != null ?
 
-                 new TcpClient(_localEndPoint) :
 
-                 new TcpClient(_remoteEndPoint.Address.AddressFamily);            
 
-             SetSocketOptions();
 
-             var ar = _tcpClient.BeginConnect(_remoteEndPoint.Address, _remoteEndPoint.Port, null, _tcpClient);
 
-             if (!ar.AsyncWaitHandle.WaitOne(ConnectTimeout))
 
-             {
 
-                 Close(false);
 
-                 throw new TimeoutException(string.Format(
 
-                     "Connect to [{0}] timeout [{1}].", _remoteEndPoint, ConnectTimeout));
 
-             }
 
-             try
 
-             {
 
-                 _tcpClient.EndConnect(ar);
 
-             }
 
-             catch (Exception ex)
 
-             {
 
-                 Close(false);
 
-                 throw ex;
 
-             }
 
-  
 
-             if (Interlocked.CompareExchange(ref _state, _connected, _connecting) != _connecting)
 
-             {
 
-                 Close(false);
 
-                 throw new InvalidOperationException("This tcp socket client is in invalid state when connected.");
 
-             }
 
-             if (_receiveBuffer == default(ArraySegment<byte>))
 
-                 _receiveBuffer = _configuration.BufferManager.BorrowBuffer();
 
-             _receiveBufferOffset = 0;
 
-             HandleTcpServerConnected();
 
-         }
 
-         public void Close()
 
-         {
 
-             Close(true);
 
-         }
 
-         private void Close(bool shallNotifyUserSide)
 
-         {
 
-             if (Interlocked.Exchange(ref _state, _closed) == _closed)
 
-             {
 
-                 return;
 
-             }
 
-             Clean();
 
-             if (shallNotifyUserSide)
 
-             {
 
-                 try
 
-                 {
 
-                     RaiseServerDisconnected();
 
-                 }
 
-                 catch (Exception ex)
 
-                 {
 
-                     HandleUserSideError(ex);
 
-                 }
 
-             }
 
-         }
 
-         private void Clean()
 
-         {
 
-             try
 
-             {
 
-                 try
 
-                 {
 
-                     if (_stream != null)
 
-                     {
 
-                         _stream.Dispose();
 
-                     }
 
-                 }
 
-                 catch { }
 
-                 try
 
-                 {
 
-                     if (_tcpClient != null)
 
-                     {
 
-                         _tcpClient.Close();
 
-                     }
 
-                 }
 
-                 catch { }
 
-             }
 
-             catch { }
 
-             finally
 
-             {
 
-                 _stream = null;
 
-                 _tcpClient = null;
 
-             }
 
-             if (_receiveBuffer != default(ArraySegment<byte>))
 
-                 _configuration.BufferManager.ReturnBuffer(_receiveBuffer);
 
-             _receiveBuffer = default(ArraySegment<byte>);
 
-             _receiveBufferOffset = 0;
 
-         }
 
-         #endregion
 
-         #region Receive
 
-         private void HandleTcpServerConnected()
 
-         {
 
-             try
 
-             {
 
-                 _stream = NegotiateStream(_tcpClient.GetStream());
 
-                 bool isErrorOccurredInUserSide = false;
 
-                 try
 
-                 {
 
-                     RaiseServerConnected();
 
-                 }
 
-                 catch (Exception ex)
 
-                 {
 
-                     isErrorOccurredInUserSide = true;
 
-                     HandleUserSideError(ex);
 
-                 }
 
-                 if (!isErrorOccurredInUserSide)
 
-                 {
 
-                     ContinueReadBuffer();
 
-                 }
 
-                 else
 
-                 {
 
-                     Close();
 
-                 }
 
-             }
 
-             catch (Exception ex)
 
-             {
 
-                 LOG.Error(ex.Message, ex);
 
-                 Close();
 
-             }
 
-         }
 
-         private void SetSocketOptions()
 
-         {
 
-             _tcpClient.ReceiveBufferSize = _configuration.ReceiveBufferSize;
 
-             _tcpClient.SendBufferSize = _configuration.SendBufferSize;
 
-             _tcpClient.ReceiveTimeout = (int)_configuration.ReceiveTimeout.TotalMilliseconds;
 
-             _tcpClient.SendTimeout = (int)_configuration.SendTimeout.TotalMilliseconds;
 
-             _tcpClient.NoDelay = _configuration.NoDelay;
 
-             _tcpClient.LingerState = _configuration.LingerState;
 
-             if (_configuration.KeepAlive)
 
-             {
 
-                 _tcpClient.Client.SetSocketOption(
 
-                     SocketOptionLevel.Socket,
 
-                     SocketOptionName.KeepAlive,
 
-                     (int)_configuration.KeepAliveInterval.TotalMilliseconds);
 
-             }
 
-             _tcpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, _configuration.ReuseAddress);
 
-         }
 
-         private Stream NegotiateStream(Stream stream)
 
-         {
 
-             if (!_configuration.SslEnabled)
 
-                 return stream;
 
-             var validateRemoteCertificate = new RemoteCertificateValidationCallback(
 
-                 (object sender,
 
-                 X509Certificate certificate,
 
-                 X509Chain chain,
 
-                 SslPolicyErrors sslPolicyErrors)
 
-                 =>
 
-                 {
 
-                     if (sslPolicyErrors == SslPolicyErrors.None)
 
-                         return true;
 
-                     if (_configuration.SslPolicyErrorsBypassed)
 
-                         return true;
 
-                     else
 
-                         LOG.Write(string.Format("Error occurred when validating remote certificate: [{0}], [{1}].",
 
-                             this.RemoteEndPoint, sslPolicyErrors));
 
-                     return false;
 
-                 });
 
-             var sslStream = new SslStream(
 
-                 stream,
 
-                 false,
 
-                 validateRemoteCertificate,
 
-                 null,
 
-                 _configuration.SslEncryptionPolicy);
 
-             IAsyncResult ar = null;
 
-             if (_configuration.SslClientCertificates == null || _configuration.SslClientCertificates.Count == 0)
 
-             {
 
-                 ar = sslStream.BeginAuthenticateAsClient( // No client certificates are used in the authentication. The certificate revocation list is not checked during authentication.
 
-                     _configuration.SslTargetHost, // The name of the server that will share this SslStream. The value specified for targetHost must match the name on the server's certificate.
 
-                     null, _tcpClient);
 
-             }
 
-             else
 
-             {
 
-                 ar = sslStream.BeginAuthenticateAsClient(
 
-                     _configuration.SslTargetHost, // The name of the server that will share this SslStream. The value specified for targetHost must match the name on the server's certificate.
 
-                     _configuration.SslClientCertificates, // The X509CertificateCollection that contains client certificates.
 
-                     _configuration.SslEnabledProtocols, // The SslProtocols value that represents the protocol used for authentication.
 
-                     _configuration.SslCheckCertificateRevocation, // A Boolean value that specifies whether the certificate revocation list is checked during authentication.
 
-                     null, _tcpClient);
 
-             }
 
-             if (!ar.AsyncWaitHandle.WaitOne(ConnectTimeout))
 
-             {
 
-                 Close(false);
 
-                 throw new TimeoutException(string.Format(
 
-                     "Negotiate SSL/TSL with remote [{0}] timeout [{1}].", this.RemoteEndPoint, ConnectTimeout));
 
-             }
 
-             sslStream.EndAuthenticateAsClient(ar);
 
-             // When authentication succeeds, you must check the IsEncrypted and IsSigned properties 
 
-             // to determine what security services are used by the SslStream. 
 
-             // Check the IsMutuallyAuthenticated property to determine whether mutual authentication occurred.
 
-             LOG.Write(string.Format(
 
-                 "Ssl Stream: SslProtocol[{0}], IsServer[{1}], IsAuthenticated[{2}], IsEncrypted[{3}], IsSigned[{4}], IsMutuallyAuthenticated[{5}], "
 
-                 + "HashAlgorithm[{6}], HashStrength[{7}], KeyExchangeAlgorithm[{8}], KeyExchangeStrength[{9}], CipherAlgorithm[{10}], CipherStrength[{11}].",
 
-                 sslStream.SslProtocol,
 
-                 sslStream.IsServer,
 
-                 sslStream.IsAuthenticated,
 
-                 sslStream.IsEncrypted,
 
-                 sslStream.IsSigned,
 
-                 sslStream.IsMutuallyAuthenticated,
 
-                 sslStream.HashAlgorithm,
 
-                 sslStream.HashStrength,
 
-                 sslStream.KeyExchangeAlgorithm,
 
-                 sslStream.KeyExchangeStrength,
 
-                 sslStream.CipherAlgorithm,
 
-                 sslStream.CipherStrength));
 
-             return sslStream;
 
-         }
 
-         private void ContinueReadBuffer()
 
-         {
 
-             try
 
-             {
 
-                 _stream.BeginRead(
 
-                     _receiveBuffer.Array,
 
-                     _receiveBuffer.Offset + _receiveBufferOffset,
 
-                     _receiveBuffer.Count - _receiveBufferOffset,
 
-                     HandleDataReceived,
 
-                     _stream);               
 
-             }
 
-             catch (Exception ex)
 
-             {
 
-                 if (!CloseIfShould(ex))
 
-                     throw;
 
-             }
 
-         }
 
-         private void HandleDataReceived(IAsyncResult ar)
 
-         {
 
-             if (this.State != TcpSocketConnectionState.Connected)
 
-                 return;
 
-             try
 
-             {
 
-                 // when callback to here the stream may have been closed
 
-                 if (_stream == null)
 
-                     return;
 
-                 int numberOfReadBytes = 0;
 
-                 try
 
-                 {
 
-                     // The EndRead method blocks until data is available. The EndRead method reads 
 
-                     // as much data as is available up to the number of bytes specified in the size 
 
-                     // parameter of the BeginRead method. If the remote host shuts down the Socket 
 
-                     // connection and all available data has been received, the EndRead method 
 
-                     // completes immediately and returns zero bytes.
 
-                     numberOfReadBytes = _stream.EndRead(ar);
 
-                 }
 
-                 catch (Exception)
 
-                 {
 
-                     // unable to read data from transport connection, 
 
-                     // the existing connection was forcibly closed by remote host
 
-                     numberOfReadBytes = 0;
 
-                 }
 
-                 if (numberOfReadBytes == 0)
 
-                 {
 
-                     // connection has been closed
 
-                     Close();
 
-                     return;
 
-                 }
 
-                 ReceiveBuffer(numberOfReadBytes);
 
-                 ContinueReadBuffer();
 
-             }
 
-             catch (Exception ex)
 
-             {
 
-                 if (!CloseIfShould(ex))
 
-                     throw;
 
-             }
 
-         }
 
-         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 Strip 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;
 
-             int consumedLength = 0;
 
-             SegmentBufferDeflector.ReplaceBuffer(_configuration.BufferManager, ref _receiveBuffer, ref _receiveBufferOffset, receiveCount);
 
-             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
 
-                     {
 
-                         RaiseServerDataReceived(payload, payloadOffset, payloadCount);
 
-                     }
 
-                     catch (Exception ex)
 
-                     {
 
-                         HandleUserSideError(ex);
 
-                     }
 
-                     finally
 
-                     {
 
-                         consumedLength += frameLength;
 
-                     }
 
-                 }
 
-                 else
 
-                 {
 
-                     break;
 
-                 }
 
-             }
 
-             try
 
-             {
 
-                 SegmentBufferDeflector.ShiftBuffer(_configuration.BufferManager, consumedLength, ref _receiveBuffer, ref _receiveBufferOffset);
 
-             }
 
-             catch (ArgumentOutOfRangeException) { }
 
-         }
 
-         #endregion
 
-         #region Exception Handler
 
-         private bool IsSocketTimeOut(Exception ex)
 
-         {
 
-             return ex is IOException
 
-                 && ex.InnerException != null
 
-                 && ex.InnerException is SocketException
 
-                 && (ex.InnerException as SocketException).SocketErrorCode == SocketError.TimedOut;
 
-         }
 
-         private bool CloseIfShould(Exception ex)
 
-         {
 
-             if (ex is ObjectDisposedException
 
-                 || ex is InvalidOperationException
 
-                 || ex is SocketException
 
-                 || ex is IOException
 
-                 || ex is NullReferenceException
 
-                 )
 
-             {
 
-                 LOG.Error(ex.Message, ex);
 
-                 Close();
 
-                 return true;
 
-             }
 
-             return false;
 
-         }
 
-         private void HandleUserSideError(Exception ex)
 
-         {
 
-             LOG.Error(string.Format("Client [{0}] error occurred in user side [{1}].", this, ex.Message), ex);
 
-         }
 
-         #endregion
 
-         #region Send
 
-         public bool Send(byte[] data)
 
-         {
 
-             if (data == null)
 
-                 throw new ArgumentNullException("data");
 
-             return Send(data, 0, data.Length);
 
-         }
 
-         public bool Send(byte[] data, int offset, int count)
 
-         {
 
-             BufferValidator.ValidateBuffer(data, offset, count, "data");
 
-             if (this.State != TcpSocketConnectionState.Connected)
 
-             {
 
-                 return false;
 
-                 throw new InvalidProgramException("This client has not connected to server.");
 
-                 
 
-             }
 
-             try
 
-             {
 
-                 byte[] frameBuffer;
 
-                 int frameBufferOffset;
 
-                 int frameBufferLength;
 
-                 _configuration.FrameBuilder.Encoder.EncodeFrame(data, offset, count, out frameBuffer, out frameBufferOffset, out frameBufferLength);
 
-                 _stream.Write(frameBuffer, frameBufferOffset, frameBufferLength);
 
-                 return true;
 
-             }
 
-             catch (Exception ex)
 
-             {
 
-                 if (IsSocketTimeOut(ex))
 
-                 {
 
-                     LOG.Error(ex.Message, ex);
 
-                     return false;
 
-                 }
 
-                 else
 
-                 {
 
-                     if (!CloseIfShould(ex)) return false;
 
-                     //throw;
 
-                 }
 
-             }
 
-             return false;
 
-         }
 
-         public void BeginSend(byte[] data)
 
-         {
 
-             if (data == null)
 
-                 throw new ArgumentNullException("data");
 
-             BeginSend(data, 0, data.Length);
 
-         }
 
-         public void BeginSend(byte[] data, int offset, int count)
 
-         {
 
-             BufferValidator.ValidateBuffer(data, offset, count, "data");
 
-             if (this.State != TcpSocketConnectionState.Connected)
 
-             {
 
-                 throw new InvalidProgramException("This client has not connected to server.");
 
-             }
 
-             try
 
-             {
 
-                 byte[] frameBuffer;
 
-                 int frameBufferOffset;
 
-                 int frameBufferLength;
 
-                 _configuration.FrameBuilder.Encoder.EncodeFrame(data, offset, count, out frameBuffer, out frameBufferOffset, out frameBufferLength);
 
-                 _stream.BeginWrite(frameBuffer, frameBufferOffset, frameBufferLength, HandleDataWritten, _stream);
 
-             }
 
-             catch (Exception ex)
 
-             {
 
-                 if (IsSocketTimeOut(ex))
 
-                 {
 
-                     LOG.Error(ex.Message, ex);
 
-                 }
 
-                 else
 
-                 {
 
-                     if (!CloseIfShould(ex))
 
-                         throw;
 
-                 }
 
-             }
 
-         }
 
-         private void HandleDataWritten(IAsyncResult ar)
 
-         {
 
-             try
 
-             {
 
-                 _stream.EndWrite(ar);
 
-             }
 
-             catch (Exception ex)
 
-             {
 
-                 if (!CloseIfShould(ex))
 
-                     throw;
 
-             }
 
-         }
 
-         public IAsyncResult BeginSend(byte[] data, AsyncCallback callback, object state)
 
-         {
 
-             if (data == null)
 
-                 throw new ArgumentNullException("data");
 
-             return BeginSend(data, 0, data.Length, callback, state);
 
-         }
 
-         public IAsyncResult BeginSend(byte[] data, int offset, int count, AsyncCallback callback, object state)
 
-         {
 
-             BufferValidator.ValidateBuffer(data, offset, count, "data");
 
-             if (this.State != TcpSocketConnectionState.Connected)
 
-             {
 
-                 throw new InvalidProgramException("This client has not connected to server.");
 
-             }
 
-             try
 
-             {
 
-                 byte[] frameBuffer;
 
-                 int frameBufferOffset;
 
-                 int frameBufferLength;
 
-                 _configuration.FrameBuilder.Encoder.EncodeFrame(data, offset, count, out frameBuffer, out frameBufferOffset, out frameBufferLength);
 
-                 return _stream.BeginWrite(frameBuffer, frameBufferOffset, frameBufferLength, callback, state);
 
-             }
 
-             catch (Exception ex)
 
-             {
 
-                 if (IsSocketTimeOut(ex))
 
-                 {
 
-                     LOG.Error(ex.Message, ex);
 
-                 }
 
-                 else
 
-                 {
 
-                     if (!CloseIfShould(ex))
 
-                         throw;
 
-                 }
 
-                 throw;
 
-             }
 
-         }
 
-         public void EndSend(IAsyncResult asyncResult)
 
-         {
 
-             HandleDataWritten(asyncResult);
 
-         }
 
-         #endregion
 
-         #region Events
 
-         public event EventHandler<TcpServerConnectedEventArgs> ServerConnected;
 
-         public event EventHandler<TcpServerDisconnectedEventArgs> ServerDisconnected;
 
-         public event EventHandler<TcpServerDataReceivedEventArgs> ServerDataReceived;
 
-         private void RaiseServerConnected()
 
-         {
 
-             if (ServerConnected != null)
 
-             {
 
-                 ServerConnected(this, new TcpServerConnectedEventArgs(this.RemoteEndPoint, this.LocalEndPoint));
 
-             }
 
-         }
 
-         private void RaiseServerDisconnected()
 
-         {
 
-             if (ServerDisconnected != null)
 
-             {
 
-                 ServerDisconnected(this, new TcpServerDisconnectedEventArgs(_remoteEndPoint, _localEndPoint));
 
-             }
 
-         }
 
-         private void RaiseServerDataReceived(byte[] data, int dataOffset, int dataLength)
 
-         {
 
-             if (ServerDataReceived != null)
 
-             {
 
-                 ServerDataReceived(this, new TcpServerDataReceivedEventArgs(this, data, dataOffset, dataLength));
 
-             }
 
-         }
 
-         #endregion
 
-         #region IDisposable Members
 
-         public void Dispose()
 
-         {
 
-             Dispose(true);
 
-             GC.SuppressFinalize(this);
 
-         }
 
-         protected virtual void Dispose(bool disposing)
 
-         {
 
-             if (disposing)
 
-             {
 
-                 try
 
-                 {
 
-                     Close();
 
-                 }
 
-                 catch (Exception ex)
 
-                 {
 
-                     LOG.Error(ex.Message, ex);
 
-                 }
 
-             }
 
-         }
 
-         #endregion
 
-     }
 
- }
 
 
  |