public int Write(byte[] buffer, int offset, int size, int timeout)
        {
            try
            {
                lock (_writeSyncObject) //Can't write at the same time from different threads
                {
                    if (!TcpClient.Client.Connected)
                    {
                        throw new NotConnectedException();
                    }
                    if (_netStream == null)
                    {
                        throw new NotConnectedException();
                    }

                    TcpClient.SendTimeout = timeout;

                    SocketError err;
                    var         sendedBytes = TcpClient.Client.Send(buffer, offset, size, SocketFlags.None, out err);
                    _netStream.Flush();
                    if (err != SocketError.Success)
                    {
                        Exception ex;
                        if (err == SocketError.ConnectionAborted)
                        {
                            ex = new NotConnectedException();
                        }
                        else
                        {
                            ex = new NetworkWriteException(err.ToString());
                        }
                        throw ex;
                    }
                    return(sendedBytes);
                }
            }
            catch (NotConnectedException)
            {
                IsConnected = false;
            }
            catch (Exception ex)
            {
                OnErrorEvent(ex);
            }
            return(0);
        }
        public int Write(byte[] buffer, int offset, int size, int timeout)
        {
            try
            {
                lock (_writeSyncObject) //Can't write at the same time from different threads
                {
                    if (_isSocketDisposed)
                    {
                        return(0);
                    }
                    if (Socket == null)
                    {
                        throw new NotConnectedException();
                    }
                    if (!Socket.Connected)
                    {
                        throw new NotConnectedException();
                    }

                    Socket.SendTimeout = timeout;

                    SocketError err;
                    var         sendedBytes = Socket.Send(buffer, offset, size, SocketFlags.None, out err);

                    if (err != SocketError.Success)
                    {
                        Exception ex;
                        switch (err)
                        {
                        case SocketError.ConnectionAborted:
                        case SocketError.ConnectionReset:
                        case SocketError.ConnectionRefused:
                        case SocketError.Interrupted:
                        case SocketError.TimedOut:
                            ex = new NotConnectedException();
                            break;

                        default:
                            ex = new NetworkWriteException(err.ToString());
                            break;
                        }
                        throw ex;
                    }

                    return(sendedBytes);
                }
            }
            catch (NotConnectedException)
            {
                IsConnected = false;
            }
            catch (ThreadAbortException)
            {
            }
            catch (SocketException sex)
            {
                switch (sex.SocketErrorCode)
                {
                case SocketError.ConnectionAborted:
                case SocketError.ConnectionReset:
                case SocketError.ConnectionRefused:
                case SocketError.Interrupted:
                case SocketError.TimedOut:
                    IsConnected = false;
                    break;

                default:
                    OnErrorEvent(sex);
                    break;
                }
            }
            catch (ObjectDisposedException)
            {
            }
            catch (Exception ex)
            {
                var type = ex.GetType();
                if (ex.InnerException != null && ex.InnerException.GetType() != typeof(ThreadAbortException))
                {
                    OnErrorEvent(ex);
                }
            }
            return(0);
        }