/// <summary> /// Callback method for asynchronous read /// </summary> /// <param name="ar"></param> public void ReadCallBack(IAsyncResult ar) { TcpState tcpState = (TcpState)ar.AsyncState; NetworkStream networkStream = tcpState.NetworkStream; try { int bytesRead = networkStream.EndRead(ar); if (bytesRead > 0) { // Send back received date byte[] receivedData = new byte[bytesRead]; Array.Copy(tcpState.DataBuffer, receivedData, bytesRead); networkStream.Write(receivedData, 0, receivedData.Length); // Raise event if (OnDataReceived != null) { OnDataReceived(receivedData); } // Reset timeouut watch tcpState.TimeoutWatch = DateTime.Now; networkStream.BeginRead(tcpState.DataBuffer, 0, tcpState.DataBuffer.Length, new AsyncCallback(ReadCallBack), tcpState); } else { // We are hooked in CLOSE_WAIT state, so close tcpClient.Client.Close(); } } catch (IOException ioException) { // Rethrow every exception that is not socketException if (ioException.InnerException.GetType() == typeof(SocketException)) { SocketException socketException = (SocketException)ioException.InnerException; // Report every error but ConnectionReset if (socketException.SocketErrorCode != SocketError.ConnectionReset && OnSocketException != null) { OnSocketException(socketException); Stop(); } } else if (ioException.InnerException.GetType() != typeof(ObjectDisposedException)) { throw ioException; } } }
/// <summary> /// Main thread method /// </summary> private void ServerThread() { try { // Start listening tcpListener.Start(); // Main loop while (serverRunning) { tcpClient = tcpListener.AcceptTcpClient(); // Raise event when client is connected if (OnConnect != null) { OnConnect(tcpClient.Client.RemoteEndPoint); } // Start exchanging the data when client is connected if (tcpClient != null && tcpClient.Client.Connected) { // Init state object TcpState tcpState = new TcpState(); tcpState.NetworkStream = new NetworkStream(tcpClient.Client); tcpState.DataBuffer = new byte[tcpClient.ReceiveBufferSize]; tcpState.TimeoutWatch = DateTime.Now; tcpState.NetworkStream.BeginRead(tcpState.DataBuffer, 0, tcpState.DataBuffer.Length, new AsyncCallback(ReadCallBack), tcpState); bool timeOut = false; while (tcpClient.Client.Connected && serverRunning && !timeOut) { TimeSpan timeoutSpan = DateTime.Now - tcpState.TimeoutWatch; if (timeoutSpan.Seconds >= ConnectionTimeout) { timeOut = true; } } // Raise disconnect event if (OnDisconnect != null) { OnDisconnect(timeOut); } tcpClient.Close(); } } } catch (SocketException socketException) { // Report every error but Interrupted, thrown by tcpListener when stopping the server if (socketException.SocketErrorCode != SocketError.Interrupted && OnSocketException != null) { OnSocketException(socketException); Stop(); } } Stop(); }