C # network communication framework networkcomms kernel parsing 5 Data listening,
This article is based on the open-source gplv3 protocol of networkcomms2.3.1.
In networkcomms, the server can listen to data synchronously or asynchronously.
Take open-source networkcomms.2.31 as an Example
Server listening code:
Protected override void StartIncomingDataListen () {if (! NetworkComms. connectionExists (ConnectionInfo. remoteEndPoint, ConnectionType. TCP) {CloseConnection (true, 18); throw new ConnectionSetupException ("A connection reference by endPoint shocould exist before starting an incoming data listener. ") ;}# if WINDOWS_PHONE var stream = socket. inputStream. asStreamForRead (); stream. beginRead (dataBuffer, 0, dataBuffer. length, new AsyncCallback (IncomingTCPPacketHandler), stream); # else lock (delegateLocker) {// synchronous listening mode if (NetworkComms. connectionListenModeUseSync) {if (incomingDataListenThread = null) {incomingDataListenThread = new Thread (callback); // Incoming data always gets handled in a time critical fashion incomingDataListenThread. priority = NetworkComms. timeCriticalThreadPriority; incomingDataListenThread. name = "IncomingDataListener"; incomingDataListenThread. start () ;}// asynchronous listening mode else tcpClientNetworkStream. beginRead (dataBuffer, 0, dataBuffer. length, new AsyncCallback (IncomingTCPPacketHandler), tcpClientNetworkStream);} # endif if (NetworkComms. loggingEnabled) NetworkComms. logger. trace ("Listening for incoming data from" + ConnectionInfo );}
Let's take asynchronous listening as an example to analyze the process of the data that the listener enters (similar to synchronous listening)
/// <Summary> /// Asynchronous incoming connection data delegate /// </summary> /// <param name = "ar"> The call back state object </param> void IncomingTCPPacketHandler (IAsyncResult ar) {// Initialised with true so that logic still works in WP8 bool dataAvailable = true; # if! WINDOWS_PHONE // Incoming data always gets handled in a timeCritical fashion at this point Thread. currentThread. priority = NetworkComms. timeCriticalThreadPriority; // int bytesRead; # endif try {# if WINDOWS_PHONE var stream = ar. asyncState as Stream; var count = stream. endRead (ar); totalBytesRead = count + totalBytesRead; # else NetworkStream netStream = (NetworkStream) ar. asyncState; if (! NetStream. canRead) throw new ObjectDisposedException ("Unable to read from stream. "); totalBytesRead = netStream. endRead (ar) + totalBytesRead; dataAvailable = netStream. dataAvailable; # endif if (totalBytesRead> 0) {// After receiving the data, update ConnectionInfo. updateLastTrafficTime (); // If we have read a single byte which is 0 and we are not expecting other data if (totalBytesRead = 1 & dataBuffer [0] = 0 & packetBuilder. totalBytesExpected-packetBuilder. totalBytesCached = 0) {if (NetworkComms. loggingEnabled) NetworkComms. logger. trace ("... null packet removed in IncomingPacketHandler () from "+ ConnectionInfo + ". 1 ");} else {// if (NetworkComms. loggingEnabled) NetworkComms. logger. trace ("... "+ totalBytesRead. toString () + "bytes added to packetBuilder. "); // If there is more data to ge T then add it to the packets lists; // add data to packetBuilder. AddPartialPacket (totalBytesRead, dataBuffer); # if! WINDOWS_PHONE // If we have more data we might as well continue reading syncronously // In order to deal with data as soon as we think we have sufficient we will leave this loop // when receiving when the incoming data is smaller than the data packet size, while (dataAvailable & packetBuilder. totalBytesCached <packetBuilder. totalBytesExpected) {int bufferOffset = 0; // We need a buffer for our incoming data // First we try to reuse a previous buffer I F (packetBuilder. totalPartialPacketCount> 0 & packetBuilder. numUnusedBytesMostRecentPartialPacket ()> 0) dataBuffer = packetBuilder. removeMostRecentPartialPacket (ref bufferOffset); else // If we have nothing to reuse we allocate a new buffer dataBuffer = new byte [NetworkComms. receiveBufferSizeBytes]; // receives data from the data stream totalBytesRead = netStream. read (dataBuffer, bufferOffset, dataBuffer. length-bufferO Ffset) + bufferOffset; if (totalBytesRead> 0) {ConnectionInfo. updateLastTrafficTime (); // If we have read a single byte which is 0 and we are not expecting other data if (totalBytesRead = 1 & dataBuffer [0] = 0 & packetBuilder. totalBytesExpected-packetBuilder. totalBytesCached = 0) {if (NetworkComms. loggingEnabled) NetworkComms. logger. trace ("... null packet removed in IncomingPacketHandler () From "+ ConnectionInfo + ". 2 "); // LastTrafficTime = DateTime. now;} else {// if (NetworkComms. loggingEnabled) NetworkComms. logger. trace ("... "+ totalBytesRead. toString () + "bytes added to packetBuilder for connection with" + ConnectionInfo + ". cached "+ packetBuilder. totalBytesCached. toString () + "B, expecting" + packetBuilder. totalBytesExpected. toString () + "B. "); packetBuilder. addPar TialPacket (totalBytesRead, dataBuffer); dataAvailable = netStream. dataAvailable ;}} else break ;}# endif }// if the received data is sufficient if (packetBuilder. totalBytesCached> 0 & packetBuilder. totalBytesCached> = packetBuilder. totalBytesExpected) {// Once we think we might have enough data we call the incoming packet handle handoff // shocould we have a complete packet this method will start the appriate task // T His method will now clear byes from the incoming packets if we have already ed something complete. // call the IncomingPacketHandleHandOff method to process the received byte data in packetBuilder, restore the binary data to the corresponding type, and process IncomingPacketHandleHandOff (packetBuilder );} if (totalBytesRead = 0 &&(! DataAvailable | ConnectionInfo. connectionState = ConnectionState. shutdown) CloseConnection (false,-2); else {// We need a buffer for our incoming data // First we try to reuse a previous buffer if (packetBuilder. totalPartialPacketCount> 0 & packetBuilder. numUnusedBytesMostRecentPartialPacket ()> 0) dataBuffer = packetBuilder. removeMostRecentPartialPacket (ref totalBytesRead); else {// If we have Nothing to reuse we allocate a new buffer dataBuffer = new byte [NetworkComms. receiveBufferSizeBytes]; totalBytesRead = 0 ;}# if WINDOWS_PHONE stream. beginRead (dataBuffer, totalBytesRead, dataBuffer. length-totalBytesRead, IncomingTCPPacketHandler, stream); # else // continues to receive data netStream on TCP connections. beginRead (dataBuffer, totalBytesRead, dataBuffer. length-totalBytesRead, IncomingTCPPacketHandler, netStream ); # Endif }} catch (IOException) {CloseConnection (true, 12);} catch (ObjectDisposedException) {CloseConnection (true, 13);} catch (SocketException) {CloseConnection (true, 14);} catch (InvalidOperationException) {CloseConnection (true, 15);} catch (Exception ex) {NetworkComms. logError (ex, "Error_TCPConnectionIncomingPacketHandler"); CloseConnection (true, 31) ;}# if! WINDOWS_PHONE Thread. CurrentThread. Priority = ThreadPriority. Normal; # endif}
The received data is handed over to PacketBuilder for processing. The following chapter analyzes how PacketBuilder processes the received binary data.
Www.cnblogs.com/networkcomms
Www.networkcomms.cn