Example #1
0
        /// <summary>
        /// 发送一个消息包
        /// </summary>
        /// <param name="packet"></param>
        /// <param name="needencrypt">是否加密</param>
        /// <returns></returns>
        public override void SendPacket(Packet packet, bool encrypt_if_need)
        {
            if (m_sendlock == null)
            {
                UnityEngine.Debug.Log("m_sendlock == null");
                return;
            }

            lock (this)
            {
                packet.SerialNumber = m_lastSendPacketSerialNumber;
                m_lastSendPacketSerialNumber++;

                byte[]     data       = packet.ToArray();
                int        datalength = packet.Length;
                PacketFlag packetflag = packet.PacketFlag;
                //加密,压缩消息包
                if (m_secure_connection && m_connectionState == ConnectionState.Connected)
                {
                    if (tls_sendSecureBuffer == null)
                    {
                        tls_sendSecureBuffer = new byte[Packet.MaxLength];
                    }
                    //压缩
                    bool compressed = false;
#if _NC_Compress
                    if (data.Length > Packet.NeedCompressMinLength)
                    {
                        int outlen = Compress.LZO.Compress(data, Packet.NoCryptHeaderLength, data.Length - Packet.NoCryptHeaderLength,
                                                           tls_sendSecureBuffer, Packet.NoCryptHeaderLength);
                        if (outlen <= (data.Length - 20))                        //压缩有实际效果
                        {
                            //Buffer.BlockCopy(m_sendSecureBuffer, 0, data, Packet.NoCryptHeaderLength, outlen);
                            datalength = outlen + Packet.NoCryptHeaderLength;
                            Buffer.BlockCopy(data, 0, tls_sendSecureBuffer, 0, Packet.NoCryptHeaderLength);
                            if (m_compressneedchecksum)
                            {
                                uint crccheck = HashHelp.CRC32hash(tls_sendSecureBuffer, Packet.NoCryptHeaderLength, outlen);
                                ArrayUtility.SetInt(tls_sendSecureBuffer, (int)crccheck, datalength);
                                datalength += 4;
                            }
                            packetflag |= PacketFlag.Compressed;
                            data        = tls_sendSecureBuffer;
                            compressed  = true;
                        }
                    }
                    if (encrypt_if_need && m_encrypt != null)
                    {
                        if (!compressed)
                        {
                            Buffer.BlockCopy(data, 0, tls_sendSecureBuffer, 0, datalength);
                            data = tls_sendSecureBuffer;
                        }
                        m_encrypt.Encrypt(data, Packet.NoCryptHeaderLength, datalength - Packet.NoCryptHeaderLength);
                        packetflag |= PacketFlag.Encrypted;
                    }
#endif
                }

                //设置消息长度
                ArrayUtility.SetByte(data, (byte)packetflag, Packet.OffsetFlag);
                ArrayUtility.SetShort(data, (short)datalength, Packet.OffsetLength);
                this.Send(data, datalength);
            }
        }
Example #2
0
        //把底层传来的数据分多次提交给使用者。
        //每次提交的数据称为包,其大小记录在包头,所有的包顺序排列。
        //如果现存的数据不足包长,则等待后续数据。
        protected override void OnReceivedDataCallBack(byte[] data /*整个包的起始地址,已在下层进行拼接*/, int length)
        {
            if (m_connectionState == ConnectionState.Uninitialised || length <= 0)
            {
                return;
            }
            m_iSegmentSize += length;       //合并收到的包
            int startOffset     = 0;        //amount for the submits to user.
            int rawpacketlength = 0;        //user packet size

            while (m_iSegmentSize >= Packet.HeaderSize)
            {
                //从消息头中读出包长度
                m_lengthOfCurrentPacket = Util.ArrayUtility.GetShort(data, startOffset + Packet.OffsetLength);
                //包长错误,忽略此包
                if (m_lengthOfCurrentPacket < Packet.HeaderSize || m_lengthOfCurrentPacket > Packet.MaxLength)
                {
                    m_iSegmentSize = 0;
                    return;
                }
                //数据不够组成一个消息包,等待后续数据
                if (m_iSegmentSize < m_lengthOfCurrentPacket)
                {
                    break;
                }
                rawpacketlength = m_lengthOfCurrentPacket;

                //按顺序读出包ID,DispatcherID,和标记位
                m_packetIDOfCurrentPacket     = ArrayUtility.GetShort(data, startOffset + Packet.OffsetPacketID);
                m_dispatcherIDOfCurrentPacket = ArrayUtility.GetInt(data, Packet.OffsetDispatcherID + startOffset);
                m_magicnumOfCurrentPacket     = Util.ArrayUtility.GetByte(data, startOffset + Packet.OffsetFlag);

                //HandleOneRawPacket();
                //处理明文数据(不加密也不压缩)
                if ((m_magicnumOfCurrentPacket & (short)PacketFlag.Encrypted) == 0 &&
                    (m_magicnumOfCurrentPacket & (short)PacketFlag.Compressed) == 0)
                {
                    //int packetserialnum = ArrayUtility.GetInt(data, 8 + startOffset);
                    //包的序列号错误
                    //if (packetserialnum != m_lastRecvPacketSerialNumber)
                    //{
                    //    packetserialnum = m_lastRecvPacketSerialNumber;//why?
                    //    if (m_encrypt != null)//非加密连接,出错就不管了,警告一下
                    //    {
                    //        CloseConnection();
                    //        return;
                    //    }
                    //    Console.WriteLine("Error:TcpConnection packetserialnum != m_lastRecvPacketSerialNumber!");
                    //}
                    m_lastRecvPacketSerialNumber++;
                    ProcessPacket(m_packetIDOfCurrentPacket, data, m_lengthOfCurrentPacket, startOffset);
                }
                else                //解密解压消息
                {
                    int securedatalength = m_lengthOfCurrentPacket - Packet.NoCryptHeaderLength;
                    if (securedatalength <= 0 || m_encrypt == null)
                    {
                        CloseConnection();
                        return;
                    }
                    System.Buffer.BlockCopy(data, startOffset,
                                            m_lastPacketData, 0, m_lengthOfCurrentPacket);
#if _NC_Compress
                    //解密
                    if ((m_magicnumOfCurrentPacket & (short)PacketFlag.Encrypted) == (short)PacketFlag.Encrypted)
                    {
                        m_encrypt.Decrypt(m_lastPacketData, Packet.NoCryptHeaderLength, securedatalength);
                        m_magicnumOfCurrentPacket &= ~(short)PacketFlag.Encrypted;
                    }
                    //解压
                    if ((m_magicnumOfCurrentPacket & (short)PacketFlag.Compressed) == (short)PacketFlag.Compressed)
                    {
                        if (m_compressneedchecksum)
                        {                        //check src32
                            uint crccheck = (uint)ArrayUtility.GetInt(m_lastPacketData, securedatalength);
                            securedatalength -= 4;
                            uint crccomp = HashHelp.CRC32hash(m_lastPacketData, Packet.NoCryptHeaderLength, securedatalength);
                            if (crccheck != crccomp)
                            {
                                CloseConnection();
                                return;
                            }
                        }
                        if (tls_decompressbuffer == null)
                        {
                            tls_decompressbuffer = new byte[Packet.MaxLength];
                        }
                        int outlen = Compress.LZO.Decompress(m_lastPacketData, Packet.NoCryptHeaderLength, securedatalength, tls_decompressbuffer, 0);
                        if (outlen <= Packet.HeaderSize - Packet.NoCryptHeaderLength || outlen >= Packet.MaxLength - Packet.NoCryptHeaderLength)                        //解压失败
                        {
                            CloseConnection();
                            return;
                        }
                        m_magicnumOfCurrentPacket &= ~(short)PacketFlag.Compressed;
                        Buffer.BlockCopy(tls_decompressbuffer, 0, m_lastPacketData, Packet.NoCryptHeaderLength, outlen);
                        m_lengthOfCurrentPacket = (short)(Packet.NoCryptHeaderLength + outlen);
                    }
#endif
                    m_packetIDOfCurrentPacket = ArrayUtility.GetInt(m_lastPacketData, 4);
                    int packetserialnum = ArrayUtility.GetInt(m_lastPacketData, 8);
                    if (packetserialnum != m_lastRecvPacketSerialNumber)
                    {
                        packetserialnum = m_lastRecvPacketSerialNumber;                        //why?
                        CloseConnection();
                        return;
                    }
                    m_lastRecvPacketSerialNumber++;
                    ArrayUtility.SetShort(m_lastPacketData, m_magicnumOfCurrentPacket, 0);
                    m_dispatcherIDOfCurrentPacket = ArrayUtility.GetInt(m_lastPacketData, 12);
                    ProcessPacket(m_packetIDOfCurrentPacket, m_lastPacketData, m_lengthOfCurrentPacket, 0);
                }

                if (m_connectionState == ConnectionState.Uninitialised)
                {
                    return;
                }

                m_iSegmentSize -= rawpacketlength;
                startOffset    += rawpacketlength;
            }
            if (startOffset > 0 && m_iSegmentSize > 0)
            {
                System.Buffer.BlockCopy(data, startOffset, m_RecvBuffer, 0, m_iSegmentSize);
            }
        }