示例#1
0
        public static Message FromIOBuffer(IoBuffer inBuf, int dataLen)
        {
            var msg = get();

            do
            {
                if (dataLen < 12)
                {
                    break;
                }
                else
                {
                    dataLen -= 12;
                }
                msg.m_module  = inBuf.ReadInt32();
                msg.m_command = inBuf.ReadInt32();
                msg.m_flag    = inBuf.ReadInt32();
                //如果是回应消息,就要提取错误码
                if ((msg.m_flag & MSG_FLAG_RESPONSE) != 0)
                {
                    if (dataLen < 4)
                    {
                        break;
                    }
                    else
                    {
                        dataLen -= 4;
                    }
                    msg.m_code = inBuf.ReadInt32();
                }
                else
                {
                    msg.m_code = 0;
                }
                //如果有错误消息,就要提取错误消息
                if ((msg.m_flag & MSG_FLAG_ERR_MSG) != 0)
                {
                    if (dataLen < 4)
                    {
                        break;
                    }
                    else
                    {
                        dataLen -= 4;
                    }
                    var len = inBuf.ReadInt32();
                    if (len < 0 || dataLen < len)
                    {
                        break;
                    }
                    else
                    {
                        dataLen -= len;
                    }
                    msg.m_msg = inBuf.ReadOnlyStr(len);
                }
                else
                {
                    msg.m_msg = null;
                }
                //有消息体?
                if (dataLen > 0)
                {
                    var bodyBuf = new IoBuffer(dataLen);
                    inBuf.Read(bodyBuf, dataLen);
                    msg.m_body = bodyBuf;
                }
                else
                {
                    msg.m_body = null;
                }
                return(msg);
            }while (false);

            //对象放回池里
            put(msg);
            //能到这里来?那说明前面遇到break,说明数据不够长
            Util.SafeLogError("Message~fromIOBuffer数据不够长");
            //跳过还未读的
            inBuf.Skip(dataLen);
            //返回null
            return(null);
        }
        void decode(IoBuffer inBuf, List <Message> outObjList)
        {
            while (inBuf.ReadSize > 0)
            {
                //包头
                if (!m_inReceiving)
                {
                    // 检查包头数据是否足够,这里应该一种防止包出错的机制,如果上个包出错,这里可以找到当前包的包头
                    while (true)
                    {
                        if (inBuf.ReadSize < Message.PACKAGE_PRE_LENGTH)
                        {
                            return;
                        }
                        if (inBuf.PeekInt32() == Message.PACKAGE_INDETIFIER)
                        {
                            // 已检测到数据头
                            inBuf.Skip(4);
                            break;
                        }
                        else
                        {
                            // 跳过这个字节
                            inBuf.Skip(1);
                        }
                    }

                    //找到前导字节了,取本包长度
                    var packLen = inBuf.ReadInt32();
                    //如果没有数据,那至少应该8字节,数据长度字段4字节 + 检验和4字节
                    if (packLen < 8)
                    {
                        Util.SafeLogError("收到的数据包总长小于8, 包总长:{0}", packLen);
                        continue;
                    }
                    m_waitingLength = packLen - 4;   //减去数据长度字段4字节
                    m_inReceiving   = true;
                }

                //包体
                if (m_inReceiving)
                {
                    if (inBuf.ReadSize < m_waitingLength)
                    {
                        return;
                    }

                    var msgLen = m_waitingLength - 4;  //减去检验和4字节
                    m_inReceiving   = false;
                    m_waitingLength = 0;

                    //获得检验和
                    var checkSum1 = inBuf.ReadInt32();
                    //计算检验和
                    var checkSum2 = Message.BPHash(inBuf.Buffer, inBuf.ReadPos, msgLen);
                    //检验和不对?
                    if (checkSum1 != checkSum2)
                    {
                        //跳过这个包
                        inBuf.Skip(msgLen);
                        Util.SafeLogError("数据包检验和不正确, checkSum1:{0},checkSum2:{0}", checkSum1, checkSum2);
                        continue;
                    }

                    //解密数据
                    Encrypt.Tea16.DecryptInplace(inBuf.Buffer, inBuf.ReadPos, msgLen);
                    var msgObj = Message.FromIOBuffer(inBuf, msgLen);
                    //如果解析正确,加入消息列表
                    if (msgObj != null)
                    {
                        lock (outObjList)
                        {
                            outObjList.Add(msgObj);
                        }
                    }
                }
            }
        }