//接收数据回调 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())); } }
//========================================================== private void Update() { #region 从队列获取数据 while (true) { if (m_ReceiveCount <= 5) { m_ReceiveCount++; lock (m_ReceiveQueue) { if (m_ReceiveQueue.Count > 0) { //得到队列中的数据包 byte[] buffer = m_ReceiveQueue.Dequeue(); //得到加密后的数据 byte[] bufferNew = new byte[buffer.Length - 3]; bool isCompress = false; ushort crc = 0; using (ByteMemoryStream ms = new ByteMemoryStream(buffer)) { isCompress = ms.ReadBool(); crc = ms.ReadUShort(); ms.Read(bufferNew, 0, bufferNew.Length); } //先校验 int newCrc = Crc16.CalculateCrc16(bufferNew); if (newCrc == crc) { //异或得到原始数据 bufferNew = SecurityUtil.Xor(bufferNew); if (isCompress) { bufferNew = ZlibHelper.DeCompressBytes(bufferNew); } ushort protoCode = 0; byte[] ProtoContent = new byte[bufferNew.Length - 2]; //协议编号 using (ByteMemoryStream ms = new ByteMemoryStream(bufferNew)) { protoCode = ms.ReadUShort(); ms.Read(ProtoContent, 0, ProtoContent.Length); //获取数据需要派发出去 GameEntry.Event.Broadcast(protoCode, ProtoContent); } } else { Debug.Log("校验出错,不予接受"); } } else { break; } } } else { m_ReceiveCount = 0; break; } } #endregion }