private void HandleTcpClientAccepted(IAsyncResult ar) { if (!IsRunning) { return; } TcpListener tcpListener = (TcpListener)ar.AsyncState; TcpClient tcpClient = tcpListener.EndAcceptTcpClient(ar); if (!tcpClient.Connected) { return; } byte[] buffer = new byte[tcpClient.ReceiveBufferSize]; TcpClientState internalClient = new TcpClientState(tcpClient, buffer); // add client connection to cache string tcpClientKey = internalClient.TcpClient.Client.RemoteEndPoint.ToString(); _clients.AddOrUpdate(tcpClientKey, internalClient, (n, o) => { return(internalClient); }); RaiseClientConnected(tcpClient); // begin to read data NetworkStream networkStream = internalClient.NetworkStream; ContinueReadBuffer(internalClient, networkStream); // keep listening to accept next connection ContinueAcceptTcpClient(tcpListener); }
private void ContinueReadBuffer(TcpClientState internalClient, NetworkStream networkStream) { try { networkStream.BeginRead(internalClient.Buffer, 0, internalClient.Buffer.Length, HandleDatagramReceived, internalClient); } catch (ObjectDisposedException ex) { ExceptionHandler.Handle(ex); } }
private void HandleDatagramReceived(IAsyncResult ar) { if (!IsRunning) { return; } try { TcpClientState internalClient = (TcpClientState)ar.AsyncState; if (!internalClient.TcpClient.Connected) { return; } NetworkStream networkStream = internalClient.NetworkStream; int numberOfReadBytes = 0; try { // if the remote host has shutdown its connection, // read will immediately return with zero bytes. numberOfReadBytes = networkStream.EndRead(ar); } catch (Exception ex) { ExceptionHandler.Handle(ex); numberOfReadBytes = 0; } if (numberOfReadBytes == 0) { // connection has been closed TcpClientState internalClientToBeThrowAway; string tcpClientKey = internalClient.TcpClient.Client.RemoteEndPoint.ToString(); _clients.TryRemove(tcpClientKey, out internalClientToBeThrowAway); RaiseClientDisconnected(internalClient.TcpClient); return; } // received byte and trigger event notification byte[] receivedBytes = new byte[numberOfReadBytes]; Buffer.BlockCopy(internalClient.Buffer, 0, receivedBytes, 0, numberOfReadBytes); RaiseDatagramReceived(internalClient.TcpClient, receivedBytes); RaisePlaintextReceived(internalClient.TcpClient, receivedBytes); // continue listening for tcp datagram packets ContinueReadBuffer(internalClient, networkStream); } catch (InvalidOperationException ex) { ExceptionHandler.Handle(ex); } }
private void HandleDatagramReceived(IAsyncResult ar) { if (!IsRunning) { return; } try { TcpClientState internalClient = (TcpClientState)ar.AsyncState; if (!internalClient.TcpClient.Connected) { return; } NetworkStream networkStream = internalClient.NetworkStream; int numberOfReadBytes = 0; try { // if the remote host has shutdown its connection, // read will immediately return with zero bytes. numberOfReadBytes = networkStream.EndRead(ar); } catch (Exception ex) { ExceptionHandler.Handle(ex); numberOfReadBytes = 0; } if (numberOfReadBytes == 0) { // connection has been closed TcpClientState internalClientToBeThrowAway; string tcpClientKey = internalClient.TcpClient.Client.RemoteEndPoint.ToString(); _clients.TryRemove(tcpClientKey, out internalClientToBeThrowAway); RaiseClientDisconnected(internalClient.TcpClient); return; } // received byte and trigger event notification var receivedBytes = new byte[numberOfReadBytes]; Array.Copy(internalClient.Buffer, 0, receivedBytes, 0, numberOfReadBytes); // 当你看到这里时,这里的代码已经年久失修了,我并没有再进一步完善这里的 Socket 相关代码。 // 比如,没有分包组包粘包,甚至连消息头都没有定义。 // 那怎么办呢?可以参考这里: https://github.com/gaochundong/Cowboy // If you reach here for some reasons, I'm sorry the source code here hasn't been maintained for a little while. // I didn't keep update the code about socket and other related such as packet splitting or packet concatting. // So much even that I didn't define a packet header or something like the packet end delimiters. // Then, what can I do now? please take a look my new socket project: // https://github.com/gaochundong/Cowboy // Good Luck! RaiseDatagramReceived(internalClient.TcpClient, receivedBytes); RaisePlaintextReceived(internalClient.TcpClient, receivedBytes); // continue listening for tcp datagram packets ContinueReadBuffer(internalClient, networkStream); } catch (InvalidOperationException ex) { ExceptionHandler.Handle(ex); } }
private void ContinueReadBuffer(TcpClientState internalClient, NetworkStream networkStream) { try { networkStream.BeginRead(internalClient.Buffer, 0, internalClient.Buffer.Length, HandleDatagramReceived, internalClient); } catch (ObjectDisposedException ex) { ExceptionHandler.Handle(ex); } }
private void HandleTcpClientAccepted(IAsyncResult ar) { if (!IsRunning) return; TcpListener tcpListener = (TcpListener)ar.AsyncState; TcpClient tcpClient = tcpListener.EndAcceptTcpClient(ar); if (!tcpClient.Connected) return; byte[] buffer = new byte[tcpClient.ReceiveBufferSize]; TcpClientState internalClient = new TcpClientState(tcpClient, buffer); // add client connection to cache string tcpClientKey = internalClient.TcpClient.Client.RemoteEndPoint.ToString(); _clients.AddOrUpdate(tcpClientKey, internalClient, (n, o) => { return internalClient; }); RaiseClientConnected(tcpClient); // begin to read data NetworkStream networkStream = internalClient.NetworkStream; ContinueReadBuffer(internalClient, networkStream); // keep listening to accept next connection ContinueAcceptTcpClient(tcpListener); }