/// <summary> /// 封装数据包 /// </summary> /// <param name="data"></param> /// <returns></returns> private byte[] MakeData(byte[] data) { byte[] retBuffer = null; //1.判断是否压缩 bool isCompress = data.Length > mCompressLen ? true : false; if (isCompress)//进行压缩 { data = ZlibHelper.DeCompressBytes(data); } //2.先异或 data = SecurityUtil.Xor(data); //3.校验 ushort crc = Crc16.CalculateCrc16(data); using (ByteMemoryStream ms = new ByteMemoryStream()) { ms.WriteUShort((ushort)(data.Length + 3)); ms.WriteBool(isCompress); ms.WriteUShort(crc); ms.Write(data, 0, data.Length); retBuffer = ms.ToArray(); } return(retBuffer); }
//接收数据回调 private void ReceiveCallBack(IAsyncResult ar) { try { int len = m_Client.EndReceive(ar); if (len > 0)//已经接收到数据 { //把接收到的数据写入缓冲数据流的尾部 m_ReceiveMS.Position = m_ReceiveMS.Length; //把长度的字节写入数据流 m_ReceiveMS.Write(m_ReceiveBuffer, 0, len); //如果缓存数据流的长度大于2说明至少有个不完整的包传递过来,因为包头为ushort长度为2 if (m_ReceiveMS.Length > 2) { //进行循环拆分数据包 while (true) { //把数据流指针位置放在0处 m_ReceiveMS.Position = 0; //currMsgLen =包体的长度 int currMsgLen = m_ReceiveMS.ReadUShort(); //总包的长度 int currFullMsgLen = 2 + currMsgLen; if (m_ReceiveMS.Length >= currFullMsgLen) { //至少收到一个完整包 //定一包体的buffer byte[] buffer = new byte[currMsgLen]; //把数据流指针位置放在包体处 m_ReceiveMS.Position = 2; //把包体读到buffer中 m_ReceiveMS.Read(buffer, 0, currMsgLen); //把数据压入队列 lock (m_ReceiveQueue) { m_ReceiveQueue.Enqueue(buffer); } //==========处理剩余字节数组========= //剩余包长度 int remainLen = (int)m_ReceiveMS.Length - currFullMsgLen; if (remainLen > 0) { //把指针放在第一个包的尾部 m_ReceiveMS.Position = currFullMsgLen; //定义剩余字节数据组 byte[] remainBuffer = new byte[remainLen]; //把数据流得到剩余字节数组 m_ReceiveMS.Read(remainBuffer, 0, remainLen); //请空数据流 m_ReceiveMS.Position = 0; m_ReceiveMS.SetLength(0); //把剩余字节数组重新写入数据流 m_ReceiveMS.Write(remainBuffer, 0, remainBuffer.Length); remainBuffer = null; } else { //没有剩余字节 //请空数据流 m_ReceiveMS.Position = 0; m_ReceiveMS.SetLength(0); break; } } else { //还没有收到完整包 break; } } } //进行下一次接收数据包 ReceiveMsg(); } else { //服务器断开连接 Debug.Log(string.Format("服务器{0}断开连接", m_Client.RemoteEndPoint.ToString())); } } catch { //服务器断开连接 Debug.Log(string.Format("服务器{0}断开连接", m_Client.RemoteEndPoint.ToString())); } }