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(); } } }
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); } } }