/// <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); } }
//把底层传来的数据分多次提交给使用者。 //每次提交的数据称为包,其大小记录在包头,所有的包顺序排列。 //如果现存的数据不足包长,则等待后续数据。 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); } }