NetworkComms網(wǎng)絡(luò)通信框架序言
本文基于networkcomms2.3.1開源版本 gplv3協(xié)議
在networkcomms中,服務(wù)器端可以同步監(jiān)聽數(shù)據(jù),也可以異步監(jiān)聽數(shù)據(jù)。
以開源的networkcomms.2.31為例
服務(wù)器端監(jiān)聽代碼:
PRotected override void StartIncomingDataListen() { if (!NetworkComms.ConnectionExists(ConnectionInfo.RemoteEndPoint, ConnectionType.TCP)) { CloseConnection(true, 18); throw new ConnectionSetupException("A connection reference by endPoint should 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) { //同步監(jiān)聽模式 if (NetworkComms.ConnectionListenModeUseSync) { if (incomingDataListenThread == null) { incomingDataListenThread = new Thread(IncomingTCPDataSyncWorker); //Incoming data always gets handled in a time critical fashion incomingDataListenThread.Priority = NetworkComms.timeCriticalThreadPriority; incomingDataListenThread.Name = "IncomingDataListener"; incomingDataListenThread.Start(); } } //異步監(jiān)聽模式 else tcpClientNetworkStream.BeginRead(dataBuffer, 0, dataBuffer.Length, new AsyncCallback(IncomingTCPPacketHandler), tcpClientNetworkStream); }#endif if (NetworkComms.LoggingEnabled) NetworkComms.Logger.Trace("Listening for incoming data from " + ConnectionInfo); }
我們以異步監(jiān)聽為例,分析一下監(jiān)聽進(jìn)入的數(shù)據(jù)的過程(同步監(jiān)聽類似)
/// <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) { //收到數(shù)據(jù)后,更新連接信息類上的數(shù)據(jù)最后傳輸時間 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 get then add it to the packets lists; //添加數(shù)據(jù)到“數(shù)據(jù)包創(chuàng)建器”(packetBuilder)中 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 //當(dāng)接收到的數(shù)據(jù)小于數(shù)據(jù)包的大小的時候,循環(huán)接收 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 if (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]; //從數(shù)據(jù)流中接收數(shù)據(jù) totalBytesRead = netStream.Read(dataBuffer, bufferOffset, dataBuffer.Length - bufferOffset) + 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.AddPartialPacket(totalBytesRead, dataBuffer); dataAvailable = netStream.DataAvailable; } } else break; }#endif } } //如果接收到的數(shù)據(jù)足夠的多 if (packetBuilder.TotalBytesCached > 0 && packetBuilder.TotalBytesCached >= packetBuilder.TotalBytesExpected) { //Once we think we might have enough data we call the incoming packet handle handoff //Should we have a complete packet this method will start the appriate task //This method will now clear byes from the incoming packets if we have received something complete. //調(diào)用IncomingPacketHandleHandOff方法處理“數(shù)據(jù)包接收器”(packetBuilder)中已經(jīng)接收到的字節(jié)數(shù)據(jù),并把二進(jìn)制數(shù)據(jù)還原成相應(yīng)的類型,進(jìn)行處理 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 al
新聞熱點(diǎn)
疑難解答