private void OnProcessOneMsg(Cache4RecMsg msg) { MsgQue.Enqueue(msg); }
/// <summary> /// 从二级缓存CurNetBuffer解析数据 /// 拆包,粘包,半包处理,消息头解析(消息头0x127,) /// 未处理完数据(半包,不完整的数据),放到二级缓存NextNetBuffer中 /// /// 消息头结构按顺序说明 /// short headMsg /// int msgLen 这个长度包含 cmd和消息本身,不包含 headMsg和msgLen /// short cmd /// /// </summary> /// <param name="curNetBuffer"> </param> /// <param name=注意这里nEnd不是buf真实size,而是buf中有效数据size></param> private void ProcNetMessage(byte[] curNetBuffer, int effectByteNumInBuffer) { Debug.LogError("------>接受到有效位数:" + effectByteNumInBuffer); int head_msgLen_size = 6;//head(short) + msgLen(int); MemoryStream tstream = new MemoryStream(curNetBuffer); BinaryReader _BinaryReader = new BinaryReader(tstream, Encoding.UTF8); int tempBinaryReaderPos = 0; while (_BinaryReader.BaseStream.Position < effectByteNumInBuffer) { //半包处理1: 剩余数据长度小于head+msgLen,直接存入二级缓存NextNetBuffer,下一次再解析 long leftbytes = effectByteNumInBuffer - _BinaryReader.BaseStream.Position; if (leftbytes < head_msgLen_size) { //如果小于4个字节,那么交给下个BUFFER byte[] curbuffer = GetCurrentBuffer(); byte[] nextbuffer = GetNextBuffer(); for (int i = 0; i < leftbytes; i++) { nextbuffer[i] = curbuffer[_BinaryReader.BaseStream.Position + i]; } BytesNumWait4Process = (int)leftbytes; return; } short headmsg = BinaryHelper.ReadShort(_BinaryReader); if (HEAD_MSG != headmsg) { Debug.LogError("SocketDataMgr.ProcNetMessage 解析消息头错误 headmsg:" + headmsg + " HEAD:" + HEAD_MSG); //NINFO 如果heamMsg错了,是否应该略过当前消息,处理下一条消息? //下面方法有可能会找到假heamMsg,这个真假不好判断, //所以直接return可能是更好的选择,不允许出现找不到headMsg的情况 //while (BinaryHelper.ReadShort(_BinaryReader) != TcpNetMgr.HEAD_MSG) //{ // ; //} //_BinaryReader.BaseStream.Position -= 2; //tempBinaryReaderPos = (int)_BinaryReader.BaseStream.Position; //continue; return; } int msgLen = BinaryHelper.ReadInt(_BinaryReader); //半包处理2: 剩余数据长度小于msglen(一条消息的完整长度cmd+msg), //直接把headMsg +msgLen+剩余数据直接放到2级缓存NextNetBuffer中,等待下一次处理 leftbytes = effectByteNumInBuffer - _BinaryReader.BaseStream.Position; if (leftbytes < msgLen) { byte[] curbuffer = GetCurrentBuffer(); byte[] nextbuffer = GetNextBuffer(); for (int i = 0; i < leftbytes + head_msgLen_size; i++) { nextbuffer[i] = curbuffer[_BinaryReader.BaseStream.Position + i - head_msgLen_size]; } BytesNumWait4Process = (int)leftbytes + head_msgLen_size; return; } //开始缓存消息 short cmd = BinaryHelper.ReadShort(_BinaryReader); try { //NTODO 消息缓冲 //if (NetBackMgr.GetInst().NetBackAnalyzerDic.ContainsKey(cmd)) //{ // Byte[] content = _BinaryReader.ReadBytes(len); // Cache4RecMsg recevieMessage = new Cache4RecMsg(); // recevieMessage.cmd = cmd; // recevieMessage.protoLen = len; // recevieMessage.protoContent = content; // Log.e("TcpNetMgr", "ProcNetMessage", "消息id:" + cmd + " len:" + len + "进入NetBackMgr.Cache4RecMsgQueue" + " readerPos:" + _BinaryReader.BaseStream.Position, BeShowLog); // NetBackMgr.Cache4RecMsgQueue.Enqueue(recevieMessage); //} int len0 = msgLen - 2; Byte[] content = _BinaryReader.ReadBytes(msgLen - 2);//2 cmd(short) Cache4RecMsg msg = new Cache4RecMsg(); msg.SessionID = ""; msg.Cmd = cmd; msg.Data = content; OnProcessOnMsg?.Invoke(msg); } catch (Exception e) { Debug.LogError("SocketDataMgr.ProcNetMessage 缓存消息出错 cmd:" + cmd); } finally { tempBinaryReaderPos += (msgLen + 6);//head(2)+msgLen(4) if (_BinaryReader.BaseStream.Position != tempBinaryReaderPos) { Debug.LogError("SocketDataMgr.ProcNetMessage 消息处理函数读取数据错误 cmd:" + cmd); _BinaryReader.BaseStream.Position = tempBinaryReaderPos; } } //finally结束 } //while结束 } //函数结尾