/// <summary> /// 封装数据包。 /// </summary> /// <param name="data"></param> /// <returns></returns> private byte[] makeData(byte[] data) { bool isCompress = false; if (data.Length > 200) { isCompress = true; data = ZlibHelper.CompressBytes(data); } data = SecurityUtil.Xor(data); //加密 ushort crc = Crc16.CalculateCrc16(data); //校验码。 ushort bodyLen = (ushort)(data.Length + 3); //包体长度 MyMemoryStream m = new MyMemoryStream(); m.WriteUShort(bodyLen); m.WriteBool(isCompress); m.WriteUShort(crc); m.Write(data, 0, data.Length); data = m.ToArray(); m.Close(); return(data); }
private void receiveCallback(IAsyncResult ar) { int len = 0; try { len = this.socket.EndReceive(ar); //len为真实的收到的字节数 } catch (Exception) { Debug.Log("链接断了。"); } if (len > 0) { byte[] tmp = new byte[len]; Buffer.BlockCopy(this.buffer, 0, tmp, 0, len); //每次收到数据,把数据写入流末尾 myReceiveBuffer.Position = myReceiveBuffer.Length; ///流里的读写的起始位置,设定到流的末尾 myReceiveBuffer.Write(tmp, 0, tmp.Length); //把新收到的数据追加到流的末尾。 ///处理粘包的循环 while (true) { //1.从流的开头读取包体长度 myReceiveBuffer.Position = 0; ushort bodyLen = myReceiveBuffer.ReadUshort(); ushort fullLen = (ushort)(bodyLen + 2); if (myReceiveBuffer.Length >= fullLen) //说明够一个完整的包了。 { myReceiveBuffer.Position = 2; //从是否压缩的标识的位置开始读取标识。 bool isCompress = myReceiveBuffer.ReadBool(); ushort crc = myReceiveBuffer.ReadUshort(); //读取数据部分 byte[] data = new byte[bodyLen - 3]; myReceiveBuffer.Read(data, 0, data.Length); //////以上是 ,该读取的都读取出来了。。。 ushort newCrc = Crc16.CalculateCrc16(data); if (newCrc == crc) //校验通过。 { data = SecurityUtil.Xor(data); //解密 if (isCompress) //如果是经过压缩的,解个压缩。 { data = ZlibHelper.DeCompressBytes(data); } ///把接出来的数据包放入队列。主线程中再处理数据。 msgQueue.Enqueue(data);///放入队列等待主线程处理。 } ///剩余数据在容器中保留,刚处理完的,删除。 ushort remainLen = (ushort)(myReceiveBuffer.Length - fullLen); if (remainLen > 0) { byte[] remainArr = new byte[remainLen]; myReceiveBuffer.Position = fullLen; myReceiveBuffer.Read(remainArr, 0, remainArr.Length); ///清楚容器(myReceiveBuffer)里的所有内容 myReceiveBuffer.SetLength(0); myReceiveBuffer.Position = 0; //剩余部分再写回来 myReceiveBuffer.Write(remainArr, 0, remainArr.Length); } else { ///剩余部分长度为 0,,清楚容器(myReceiveBuffer)里的所有内容 myReceiveBuffer.SetLength(0); myReceiveBuffer.Position = 0; break; } } else { break; } } ///再次收下次的数据,否则只能收取一次数据。 this.socket.BeginReceive(this.buffer, 0, buffer.Length, SocketFlags.None, receiveCallback, null); } else //len==0链接断了 { Debug.Log("链接断了。"); } }