예제 #1
0
        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);
                        }
                    }
                }
            }
        }