首页 > 代码库 > Connection类之ConnectionIncomingData.cs(NetworkComms 2.3.1源码了解和学习)

Connection类之ConnectionIncomingData.cs(NetworkComms 2.3.1源码了解和学习)

networkComms.net2.3.1开源版本,基于gpl V3协议。因为不能公开3.x版本的源码,所以基于此版本进行学习。3.X版本进行了诸多改进和Bug修复,使用方法上两者相差不大。 
 /// <summary>    /// Connection对象  这个类是TcpConnection和 UDPConnnection连接类的父类    /// Connection由以下五个文件组成 大家注意到每个类前面都有个 partial关键字    /// ConnectionCreate.cs <1>    /// ConnectionDelegatesHandlers.cs <2>    /// ConnectionIncomingData.cs <3>    /// ConnectionSendClose.cs <4>    /// ConnectionStatic.cs  <5>    /// </summary>    /// 这部分负责接收数据,并交个networkcomms的优先级线程池处理    public abstract partial class Connection    {        /// <summary>        /// The <see cref="PacketBuilder"/> for this connection        /// </summary>        protected PacketBuilder packetBuilder;        /// <summary>        /// The current incoming data buffer        /// </summary>        protected byte[] dataBuffer;        /// <summary>        /// The total bytes read so far within dataBuffer        /// </summary>        protected int totalBytesRead;        /// <summary>        /// The thread listening for incoming data should we be using synchronous methods.        /// </summary>        protected Thread incomingDataListenThread = null;        /// <summary>        /// A connection specific method which triggers any requisites for accepting incoming data        /// </summary>        protected abstract void StartIncomingDataListen();        /// <summary>        /// Attempts to use the data provided in packetBuilder to recreate something usefull. If we don‘t have enough data yet that value is set in packetBuilder.        /// </summary>        /// <param name="packetBuilder">The <see cref="PacketBuilder"/> containing incoming cached data</param>        protected void IncomingPacketHandleHandOff(PacketBuilder packetBuilder)        {            try            {                if (NetworkComms.LoggingEnabled) NetworkComms.Logger.Trace(" ... checking for completed packet with " + packetBuilder.TotalBytesCached.ToString() + " bytes read.");                if (packetBuilder.TotalPartialPacketCount == 0)                    throw new Exception("Executing IncomingPacketHandleHandOff when no packets exist in packetbuilder.");                //Loop until we are finished with this packetBuilder                int loopCounter = 0;                while (true)                {                    //If we have ended up with a null packet at the front, probably due to some form of concatentation we can pull it off here                    //It is possible we have concatenation of several null packets along with real data so we loop until the firstByte is greater than 0                    if (packetBuilder.FirstByte() == 0)                    {                        if (NetworkComms.LoggingEnabled) NetworkComms.Logger.Trace(" ... null packet removed in IncomingPacketHandleHandOff() from " + ConnectionInfo + ", loop index - " + loopCounter.ToString());                        packetBuilder.ClearNTopBytes(1);                        //Reset the expected bytes to 0 so that the next check starts from scratch                        packetBuilder.TotalBytesExpected = 0;                        //If we have run out of data completely then we can return immediately                        if (packetBuilder.TotalBytesCached == 0) return;                    }                    else                    {                        //First determine the expected size of a header packet                        int packetHeaderSize = packetBuilder.FirstByte() + 1;                        //Do we have enough data to build a header?                        if (packetBuilder.TotalBytesCached < packetHeaderSize)                        {                            if (NetworkComms.LoggingEnabled) NetworkComms.Logger.Trace(" ... ... more data required for complete packet header.");                            //Set the expected number of bytes and then return                            packetBuilder.TotalBytesExpected = packetHeaderSize;                            return;                        }                        //We have enough for a header                        PacketHeader topPacketHeader;                        using(MemoryStream headerStream = packetBuilder.ReadDataSection(1, packetHeaderSize - 1))                            topPacketHeader = new PacketHeader(headerStream, NetworkComms.InternalFixedSendReceiveOptions);                        //Idiot test                        if (topPacketHeader.PacketType == null)                            throw new SerialisationException("packetType value in packetHeader should never be null");                        //We can now use the header to establish if we have enough payload data                        //First case is when we have not yet received enough data                        if (packetBuilder.TotalBytesCached < packetHeaderSize + topPacketHeader.PayloadPacketSize)                        {                            if (NetworkComms.LoggingEnabled) NetworkComms.Logger.Trace(" ... ... more data required for complete packet payload. Expecting " + (packetHeaderSize + topPacketHeader.PayloadPacketSize).ToString() + " total packet bytes.");                            //Set the expected number of bytes and then return                            packetBuilder.TotalBytesExpected = packetHeaderSize + topPacketHeader.PayloadPacketSize;                            return;                        }                        //Second case is we have enough data                        else if (packetBuilder.TotalBytesCached >= packetHeaderSize + topPacketHeader.PayloadPacketSize)                        {                            //We can either have exactly the right amount or even more than we were expecting                            //We may have too much data if we are sending high quantities and the packets have been concatenated                            //no problem!!                            SendReceiveOptions incomingPacketSendReceiveOptions = IncomingPacketSendReceiveOptions(topPacketHeader);                            if (NetworkComms.LoggingEnabled) NetworkComms.Logger.Debug("Received packet of type ‘" + topPacketHeader.PacketType + "‘ from " + ConnectionInfo + ", containing " + packetHeaderSize.ToString() + " header bytes and " + topPacketHeader.PayloadPacketSize.ToString() + " payload bytes.");                            //If this is a reserved packetType we call the method inline so that it gets dealt with immediately                            bool isReservedType = false;                            foreach (var tName in NetworkComms.reservedPacketTypeNames)                            {                                //isReservedType |= topPacketHeader.PacketType == tName;                                if (topPacketHeader.PacketType == tName)                                {                                    isReservedType = true;                                    break;                                }                            }                            //Only reserved packet types get completed inline                            if (isReservedType)                            {#if WINDOWS_PHONE                                var priority = QueueItemPriority.Normal;#else                                var priority = (QueueItemPriority)Thread.CurrentThread.Priority;#endif                                PriorityQueueItem item = new PriorityQueueItem(priority, this, topPacketHeader, packetBuilder.ReadDataSection(packetHeaderSize, topPacketHeader.PayloadPacketSize), incomingPacketSendReceiveOptions);                                if (NetworkComms.LoggingEnabled) NetworkComms.Logger.Trace(" ... handling packet type ‘" + topPacketHeader.PacketType + "‘ inline. Loop index - " + loopCounter.ToString());                                NetworkComms.CompleteIncomingItemTask(item);                            }                            else                            {                                QueueItemPriority itemPriority = (incomingPacketSendReceiveOptions.Options.ContainsKey("ReceiveHandlePriority") ? (QueueItemPriority)Enum.Parse(typeof(QueueItemPriority), incomingPacketSendReceiveOptions.Options["ReceiveHandlePriority"]) : QueueItemPriority.Normal);                                PriorityQueueItem item = new PriorityQueueItem(itemPriority, this, topPacketHeader, packetBuilder.ReadDataSection(packetHeaderSize, topPacketHeader.PayloadPacketSize), incomingPacketSendReceiveOptions);                                //QueueItemPriority.Highest is the only priority that is executed inline#if !WINDOWS_PHONE                                if (itemPriority == QueueItemPriority.Highest)                                {                                    if (NetworkComms.LoggingEnabled) NetworkComms.Logger.Trace(" ... handling packet type ‘" + topPacketHeader.PacketType + "‘ with priority HIGHEST inline. Loop index - " + loopCounter.ToString());                                    NetworkComms.CompleteIncomingItemTask(item);                                }                                else                                {                                    int threadId = NetworkComms.CommsThreadPool.EnqueueItem(item.Priority, NetworkComms.CompleteIncomingItemTask, item);                                    if (NetworkComms.LoggingEnabled) NetworkComms.Logger.Trace(" ... added completed " + item.PacketHeader.PacketType + " packet to thread pool (Q:" + NetworkComms.CommsThreadPool.QueueCount.ToString() + ", T:" + NetworkComms.CommsThreadPool.CurrentNumTotalThreads.ToString() + ", I:" + NetworkComms.CommsThreadPool.CurrentNumIdleThreads.ToString() + ") with priority " + itemPriority.ToString() + (threadId > 0 ? ". Selected threadId=" + threadId.ToString() : "") + ". Loop index=" + loopCounter.ToString() + ".");                                }#else                                int threadId = NetworkComms.CommsThreadPool.EnqueueItem(item.Priority, NetworkComms.CompleteIncomingItemTask, item);                                if (NetworkComms.LoggingEnabled) NetworkComms.Logger.Trace(" ... added completed " + item.PacketHeader.PacketType + " packet to thread pool (Q:" + NetworkComms.CommsThreadPool.QueueCount.ToString() + ", T:" + NetworkComms.CommsThreadPool.CurrentNumTotalThreads.ToString() + ", I:" + NetworkComms.CommsThreadPool.CurrentNumIdleThreads.ToString() + ") with priority " + itemPriority.ToString() + (threadId > 0 ? ". Selected threadId=" + threadId.ToString() : "") + ". Loop index=" + loopCounter.ToString() + ".");#endif                            }                            //We clear the bytes we have just handed off                            if (NetworkComms.LoggingEnabled) NetworkComms.Logger.Trace("Removing " + (packetHeaderSize + topPacketHeader.PayloadPacketSize).ToString() + " bytes from incoming packet buffer from connection with " + ConnectionInfo +".");                            packetBuilder.ClearNTopBytes(packetHeaderSize + topPacketHeader.PayloadPacketSize);                            //Reset the expected bytes to 0 so that the next check starts from scratch                            packetBuilder.TotalBytesExpected = 0;                            //If we have run out of data completely then we can return immediately                            if (packetBuilder.TotalBytesCached == 0) return;                        }                        else                            throw new CommunicationException("This should be impossible!");                    }                    loopCounter++;                }            }            catch (Exception ex)            {                //Any error, throw an exception.                if (NetworkComms.LoggingEnabled) NetworkComms.Logger.Fatal("A fatal exception occured in IncomingPacketHandleHandOff(), connection with " + ConnectionInfo + " be closed. See log file for more information.");                NetworkComms.LogError(ex, "CommsError");                CloseConnection(true, 45);            }        }        /// <summary>        /// Handle an incoming CheckSumFailResend packet type        /// </summary>        /// <param name="packetDataSection"></param>        internal void CheckSumFailResendHandler(MemoryStream packetDataSection)        {            //If we have been asked to resend a packet then we just go through the list and resend it.            SentPacket packetToReSend;            lock (sentPacketsLocker)            {                string checkSumRequested = NetworkComms.InternalFixedSendReceiveOptions.DataSerializer.DeserialiseDataObject<string>(packetDataSection,                     NetworkComms.InternalFixedSendReceiveOptions.DataProcessors, NetworkComms.InternalFixedSendReceiveOptions.Options);                if (sentPackets.ContainsKey(checkSumRequested))                    packetToReSend = sentPackets[checkSumRequested];                else                    throw new CheckSumException("There was no packet sent with a matching check sum");            }            //If we have already tried resending the packet 10 times something has gone horribly wrong            if (packetToReSend.SendCount > 10) throw new CheckSumException("Packet sent resulted in a catastropic checksum check exception.");            if (NetworkComms.LoggingEnabled) NetworkComms.Logger.Warn(" ... resending packet due to MD5 mismatch.");            //Increment send count and then resend            packetToReSend.IncrementSendCount();            SendPacket(packetToReSend.Packet);        }    }

 

来自英国剑桥的c#网络通讯框架  开源版本: networkcomms2.3.1  可以进入此页面下载 networkcomms网络通讯框架学习 

【开源下载】基于TCP网络通信的即时聊天系统(IM系统)(c#源码)

[源码下载]Demo2.模拟简单登陆-效果图 基于networkcomms2.3.1

[源码下载]Demo1 客户端从服务器获取信息(基于networkcomms2.3.1)

【开源下载】基于TCP网络通信的自动升级程序c#源码

【模板下载】分享我所使用的数据库框架

【模板下载】innosetup 制作.net安装包的模板

 

【模板下载】分享我所使用的数据库框架

Connection类之ConnectionIncomingData.cs(NetworkComms 2.3.1源码了解和学习)