コード例 #1
0
        /// <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);
        }