/// <summary> /// 拆包 /// </summary> /// <param name="buff">缓存区数据</param> /// <param name="len">数据长度</param> /// <returns></returns> public List <TSocketMessage> UnpackData(byte[] buff, int len) { // 拷贝本次有效的字节 byte[] _b = new byte[len]; Array.Copy(buff, 0, _b, 0, _b.Length); buff = _b; if (this.LBuff.Count > 0) { // 拷贝之前遗留的字节 this.LBuff.AddRange(_b); buff = this.LBuff.ToArray(); this.LBuff.Clear(); this.LBuff = new List <byte>(2); } List <TSocketMessage> list = new List <TSocketMessage>(); // 存放 data 的 Crc 校验码 ushort crc = 0; try { // 获取实际数据包体 using (MMO_MemoryStream ms = new MMO_MemoryStream(buff)) { byte[] _buff; Label_00983: #region 包头读取 // 循环读取包头 // 判断本次解析的字节是否满足常量字节数 if (ms.Length - ms.Position < ConstLength) { _buff = ms.ReadBytes((int)(ms.Length - ms.Position)); this.LBuff.AddRange(_buff); return(list); } short head11 = ms.ReadShort(); short head22 = ms.ReadShort(); // 如果未找到包头,则将字节流从上一次读取的位置向后移动一字节 if (!(head1 == head11 && head2 == head22)) { long newPosition = ms.Seek(-3, SeekOrigin.Current); goto Label_00983; } #endregion // 数据类型 byte msgType = (byte)ms.ReadByte(); // 数据体长度 int offset = ms.ReadInt(); #region 包解析 // 剩余字节数大于本次需要读取的字节数 if (offset <= (ms.Length - ms.Position)) { crc = ms.ReadUShort(); _buff = ms.ReadBytes(offset - 2); int newCrc = Crc16.CalculateCrc16(_buff); if (newCrc == crc) { _buff = SecurityUtil.Xor(_buff); list.Add(new TSocketMessage(_buff, msgType)); } } // 剩余字节数刚好小于本次读取的字节数,先存起来,等待接受剩余字节数一起解析 else { _buff = ms.ReadBytes((int)(ms.Length - ms.Position)); this.LBuff.AddRange(_buff); } #endregion } } catch (Exception ex) { throw new Exception("数据读取错误:" + ex.Message); } return(list); }