コード例 #1
0
ファイル: Connector.cs プロジェクト: Hengle/TestWithUnity5
        void _ProcessReceivedData(ref DaemonParameter daemonParameter)
        {
            RingBuffer <byte> dataBuffer = daemonParameter.daemonObject.receiveCache;

            while (!dataBuffer.IsEmpty)
            {
                // 拆包,按完整消息返回给Handler
                // 寻找魔数
                if (dataBuffer.DiscardToFirstIndexOf(0xC8, 0xEF))
                {
                    byte headLength = 0;
                    if (dataBuffer.Length >= 3)
                    {
                        // 找到了魔数,而且数据长度足够解析出消息头长度
                        // 解析出消息头长度
                        dataBuffer.Peek(2, out headLength);
                    }
                    else
                    {
                        // 消息接收长度还不够,继续接收
                        if (LogUtil.ShowDebug != null)
                        {
                            LogUtil.ShowDebug("消息头没收全,继续接收1");
                        }
                        break;
                    }
                    // 进一步解析出整个消息头
                    if (headLength > 0 && dataBuffer.Length >= headLength)
                    {
                        if (headLength < ProtocolDefine.minimalHeadLength)
                        {
                            // 万一消息头长度不满足协议定义的最小长度,说明收到了一条非本系统能够处理的协议,抛弃(直接抛弃协议头即可,协议体会自然在下一个循环里被抛弃掉)
                            dataBuffer.Discard(headLength);
                            if (LogUtil.ShowDebug != null)
                            {
                                LogUtil.ShowDebug("收到的消息头不满足系统定义的最小消息头长度,抛弃");
                            }
                            continue;
                        }
                        // 解析出了消息头长度,而且数据长度足够解析出整个消息头
                        // 解析出消息头里的必要数据
                        byte token;
                        dataBuffer.Peek(5, out token);
                        // 获得心跳标识位
                        bool heartBeat = (token & ProtocolDefine.heartBeatMask) != 0;

                        /*
                         * // 获得单向消息标识位
                         * bool oneWay = (token & ProtocolDefine.oneWayMask) != 0;
                         * // 获得响应消息标识位
                         * bool response = (token & ProtocolDefine.responseMask) != 0;
                         * // 获得加密标识位
                         * bool encrypt = (token & ProtocolDefine.encryptMask) != 0;
                         * // 获得加密方式
                         * int encryptType = (token & ProtocolDefine.encryptTypeMask) >> ProtocolDefine.encryptTypeBitRightOffset;
                         * // 获得压缩标识位
                         * bool compress = (token & ProtocolDefine.compressMask) != 0;
                         * // 获得拆分标识位
                         * bool split = (token & ProtocolDefine.splitMask) != 0;
                         */
                        // 如果是心跳消息,那么记录下收到的时间,抛弃消息头(心跳消息没有消息体,所以抛弃消息头就抛弃了整条心跳消息)
                        if (heartBeat)
                        {
                            daemonParameter.lastHeartBeatReturnTime = DateTimeUtil.NowMillisecond;
                            dataBuffer.Discard(headLength);
                            continue;
                        }
                        // @TODO: 处理拆分的包,要将不完整的包临时放入一个为超大包准备的缓存,直到所有拆开的包体都收到了再合并成完整的包
                        byte[] bodyLengthBytes = new byte[2];
                        dataBuffer.Peek(10, out bodyLengthBytes[0]);
                        dataBuffer.Peek(11, out bodyLengthBytes[1]);
                        short bodyLength = BitConverterEx.GetShort(bodyLengthBytes, 0, true);
                        if (dataBuffer.Length >= (headLength + bodyLength))
                        {
                            // 数据长度满足协议头和协议体,即完整消息已经接收到了
                            byte[] msgBytes = new byte[headLength + bodyLength];
                            if (dataBuffer.TryPull(msgBytes.Length, ref msgBytes) && daemonParameter.daemonObject.DataHandler != null)
                            {
                                daemonParameter.daemonObject.DataHandler.OnDataReceived(daemonParameter.daemonObject, msgBytes);
                            }
                        }
                        else
                        {
                            // 消息接收长度还不够,继续接收
                            if (LogUtil.ShowDebug != null)
                            {
                                LogUtil.ShowDebug("消息体没收全,继续接收");
                            }
                            break;
                        }
                    }
                    else
                    {
                        // 消息接收长度还不够,继续接收
                        if (LogUtil.ShowDebug != null)
                        {
                            LogUtil.ShowDebug("消息头没收全,继续接收2");
                        }
                        break;
                    }
                }
                else
                {
                    dataBuffer.DiscardAll();
                }
            }
        }
コード例 #2
0
 private void CheckConnectorReceive(WatchObject wo)
 {
     if (!wo.connector.IsReceiving)
     {
         // 连接器不在接收状态,那么将当前buffer中已经接收到的数据进行处理
         while (!wo.receiveBuffer.IsEmpty)
         {
             // 拆包,按完整消息返回给Handler
             // 寻找魔数
             if (!wo.receiveBuffer.DiscardToFirstIndexOf(0xC8, 0xEF))
             {
                 wo.receiveBuffer.DiscardAll();
             }
             if (wo.receiveBuffer.Length >= 8)
             {
                 // 找到了魔数,而且数据长度够一个消息头
                 // 解析消息头
                 byte[] lenBytes = new byte[2];
                 wo.receiveBuffer.Peek(2, out lenBytes[0]);
                 wo.receiveBuffer.Peek(3, out lenBytes[1]);
                 short len = BitConverterEx.GetShort(lenBytes, 0, true);
                 byte  ver;
                 wo.receiveBuffer.Peek(4, out ver);
                 byte serializeType;
                 wo.receiveBuffer.Peek(5, out serializeType);
                 byte moduleID;
                 wo.receiveBuffer.Peek(6, out moduleID);
                 byte functionID;
                 wo.receiveBuffer.Peek(7, out functionID);
                 // TODO 区分协议版本号和序列化类型?
                 // TODO 按模块号分发?
                 // 收到心跳,记录下收到的时间
                 if (moduleID == heartBeatModuleID && functionID == heartBeatReturnFunctionID)
                 {
                     wo.lastHeartBeatReturnTime = Time.realtimeSinceStartup;
                 }
                 // 消息头丢弃
                 wo.receiveBuffer.Discard(8);
                 // 如果存在协议体,那么尝试处理协议体
                 if (len > 8)
                 {
                     byte[] msgBytes = new byte[len - 8];
                     if (wo.receiveBuffer.TryPull(msgBytes.Length, ref msgBytes))
                     {
                         wo.eventHandler.OnReceive(moduleID, functionID, msgBytes);
                     }
                     else
                     {
                         // 消息接收长度还不够,继续接收
                         Debug.Log(Time.frameCount + " 继续接收1");
                         break;
                     }
                 }
             }
             else
             {
                 // 消息接收长度还不够,继续接收
                 Debug.Log(Time.frameCount + " 继续接收2");
                 break;
             }
         }
         if (wo.connected && wo.connector.State == EConnectorState.ExpectConnected && wo.connector.HasDataAvailable)
         {
             // 如果当前处于连接状态,就再次发起接收
             wo.connector.Receive(wo.receiveBuffer);
         }
     }
 }