/// <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); }
/// <summary> /// 封装数据包 /// </summary> /// <param name="data"></param> /// <returns></returns> private byte[] MakeData(byte[] data) { byte[] retBuffer = null; //1.如果数据包的长度 大于了m_CompressLen 则进行压缩 bool isCompress = data.Length > m_CompressLen ? true : false; if (isCompress) { data = ZlibHelper.CompressBytes(data); } //2.异或 data = SecurityUtil.Xor(data); //3.Crc校验 压缩后的 ushort crc = Crc16.CalculateCrc16(data); using (MMO_MemoryStream ms = new MMO_MemoryStream()) { ms.WriteUShort((ushort)(data.Length + 3)); ms.WriteBool(isCompress); ms.WriteUShort(crc); ms.Write(data, 0, data.Length); retBuffer = ms.ToArray(); } return(retBuffer); }
/// <summary> /// 创建包数据:包头+包体 /// </summary> /// <param name="buffer"></param> /// <returns></returns> private byte[] MakeData(byte[] buffer) { //1.压缩 bool isCompress = buffer.Length > m_CompressLen ? true : false; if (isCompress) { buffer = ZlibHelper.CompressBytes(buffer); } //2.CRC1校验 ushort crc = Crc16.CalculateCrc16(buffer); Console.WriteLine(crc); //3.异或 buffer = SecurityUtil.Xor(buffer); using (MMO_MemoryStream ms = new MMO_MemoryStream()) { //包头长度 压缩标识1+CRC16校验+buffer的长度 ms.WriteUShort((ushort)(buffer.Length + 3)); ms.WriteBool(isCompress); ms.WriteUShort(crc); ms.Write(buffer, 0, buffer.Length); return(ms.ToArray()); } }
/// <summary> /// 封装数据包 /// </summary> /// <param name="buffer"></param> private byte[] MakeDataPackage(byte[] buffer) { //1.压缩 bool isCompress = buffer.Length > m_CompressLen; if (isCompress) { buffer = ZlibHelper.CompressBytes(buffer); } //2.异或 buffer = SecurityUtil.Xor(buffer); //3.计算CRC ushort crc = Crc16.CalculateCrc16(buffer); byte[] retData; using (MMO_MemoryStream ms = new MMO_MemoryStream()) { ms.WriteUShort((ushort)(buffer.Length + 3)); ms.WriteBool(isCompress); ms.WriteUShort(crc); ms.Write(buffer, 0, buffer.Length); retData = ms.ToArray(); } return(retData); }
//解析服务器返回的数据包,步骤如下: //1、把包头长度去掉 //2、CRC校验, //3、检查压缩标志,先校验CRC再解压,因为打包时的CRC就是压缩后的值 //4、使用异或算法得到真实包体 //5、通过解析协议编号,派发对应的委托 void Update() { while (true) { if (mReceiveCount <= 3) { mReceiveCount++; lock (mReceiveQueue) { if (mReceiveQueue.Count > 0) { byte[] buffer = mReceiveQueue.Dequeue(); //取一个服务器返回的未处理的数据包 byte[] dataBody = new byte[buffer.Length - 3]; //获取数据包包体,未解压(压缩标志+CRC一共3字节,包头部分在数据传过来的之前就处理掉了) bool isCompress = false; //压缩标志 ushort CRC = 0; //CRC校验码 ushort protoCode = 0; //协议编号 using (MemoryStreamUtil stream = new MemoryStreamUtil(buffer)) { isCompress = stream.ReadBool(); CRC = stream.ReadUShort(); stream.Read(dataBody, 0, dataBody.Length); } ushort newCRC = Crc16.CalculateCrc16(dataBody); if (CRC == newCRC) { if (isCompress) { dataBody = ZlibHelper.DeCompressBytes(dataBody); //解压 } dataBody = SecurityUtil.XorAlgorithm(dataBody); //解密 } else { Debug.Log("client:CRC验证失败!"); break; } //开始解析原始真实数据 byte[] protoContent = new byte[dataBody.Length - 2]; //协议内容,减去协议编号 using (MemoryStreamUtil stream = new MemoryStreamUtil(dataBody)) { protoCode = stream.ReadUShort(); //这里开始使用观察者派发协议 stream.Read(protoContent, 0, protoContent.Length); SocketDispatcher.Instance.Dispatch(protoCode, protoContent); } } else { break; } } } else { mReceiveCount = 0; break; } } }
/// <summary> /// 封装数据包 /// </summary> /// <param name="data"></param> /// <returns></returns> private byte[] MakeData(byte[] data) { byte[] retBuffer = null; //1.长度压缩判断 bool isCompress = data.Length > m_CompressLen ? true : false; if (isCompress) { //2.进行压缩 data = ZlibHelper.CompressBytes(data); } //3.异或 data = SecurityUtil.Xor(data); //4.异或因子 Crc 校验码 ushort crc = Crc16.CalculateCrc16(data); Console.WriteLine("crc=" + crc); //写入 using (MMO_MemoryStream ms = new MMO_MemoryStream()) { ms.WriteUShort((ushort)(data.Length + 3)); //数据长度 ms.WriteBool(isCompress); //压缩判断 ms.WriteUShort(crc); //异或 ms.Write(data, 0, data.Length); //数据写入 retBuffer = ms.ToArray(); } return(retBuffer); }
/// <summary> /// 封装数据包 /// </summary> /// <param name="data"></param> /// <returns></returns> private byte[] MakeData(byte[] data) { byte[] retBuffer = null; //0.压缩标志 //数据包长度大于设定长度则压缩 bool isCompress = data.Length > m_CompressLength ? true : false; if (isCompress) { data = ZlibHelper.CompressBytes(data); } //1.异或 data = SecurityUtil.Xor(data); //2.CRC校验 ushort crc = Crc16.CalculateCrc16(data); using (MMO_MemoryStream ms = new MMO_MemoryStream()) { //3.写入包长度 //往ms中写入数据(包长度),数据的长度+压缩标志(1byte)+CRC校验(UShort(2byte)) ms.WriteUShort((ushort)(data.Length + 3)); //往ms中写入数据(压缩标识) ms.WriteBool(isCompress); ms.WriteUShort(crc); ms.Write(data, 0, data.Length); retBuffer = ms.ToArray(); } return(retBuffer); }
// 封装数据包 byte[] MakeData(byte[] data) { byte[] retBuffer = null; // 1.1 压缩 bool isCompress = data.Length > m_CompressLen; if (isCompress) { data = ZlibHelper.CompressBytes(data); } // 2 异或加密 data = SecurityUtil.Xor(data); // 3 加验证 ushort crc = Crc16.CalculateCrc16(data); using (MMO_MemoryStream ms = new MMO_MemoryStream()) { ms.WriteUShort((ushort)(data.Length + 3)); ms.WriteBool(isCompress); ms.WriteUShort(crc); ms.Write(data, 0, data.Length); retBuffer = ms.ToArray(); } return(retBuffer); }
/// <summary> /// 封装数据包 /// </summary> /// <param name="data"></param> /// <returns></returns> private byte[] MakeData(byte[] data) { byte[] retBuffer = null; //1.如果数据包的长度 大于了m_CompressLen 则进行压缩 bool isCompress = data.Length > m_CompressLen ? true : false; if (isCompress) { data = ZlibHelper.CompressBytes(data); } //2.异或 data = SecurityUtil.Xor(data); //3.Crc校验 压缩后的 ushort crc = Crc16.CalculateCrc16(data); Console.WriteLine("crc=" + crc); MMO_MemoryStream ms = this.m_SocketSendMS; ms.SetLength(0); ms.WriteUShort((ushort)(data.Length + 3)); ms.WriteBool(isCompress); ms.WriteUShort(crc); ms.Write(data, 0, data.Length); retBuffer = ms.ToArray(); return(retBuffer); }
protected override void OnUpdate() { base.OnUpdate(); while (true) { if (m_ReceiveCount <= 5) { m_ReceiveCount++; lock (m_ReceiveQueue) { if (m_ReceiveQueue.Count > 0) { byte[] buffer = m_ReceiveQueue.Dequeue(); bool isCompress; ushort crc; byte[] crcBuffer = new byte[buffer.Length - 3]; using (MMO_MemoryStream ms = new MMO_MemoryStream(buffer)) { isCompress = ms.ReadBool(); crc = ms.ReadUShort(); ms.Read(crcBuffer, 0, crcBuffer.Length); } if (crc == Crc16.CalculateCrc16(crcBuffer)) { crcBuffer = SecurityUtil.Xor(crcBuffer); if (isCompress) { crcBuffer = ZlibHelper.DeCompressBytes(crcBuffer); } ushort protoCode; byte[] protoContent = new byte[buffer.Length - 2]; using (MMO_MemoryStream ms = new MMO_MemoryStream(crcBuffer)) { protoCode = ms.ReadUShort(); ms.Read(protoContent, 0, protoContent.Length); } EnventDispather.Instance.Dispach(protoCode, protoContent); } else { break; } } else { break; } } } else { m_ReceiveCount = 0; break; } } }
/// <summary> /// 封包 /// </summary> /// <param name="data">待处理的数据</param> /// <returns></returns> public byte[] PackData(TSocketMessage msg, MessageType msgType) { // 封包后返回的数据 byte[] retBuffer = null; // 待封包的数据 byte[] msgBuffer = msg.MsgBuffer; // 数据类型 byte messageType = (byte)msgType; using (MMO_MemoryStream ms = new MMO_MemoryStream()) { //封装包头 ms.WriteShort(head1); ms.WriteShort(head2); //包协议 if (msgBuffer != null) { // 写入数据类型 ms.WriteByte(messageType); // 写入包体长度信息 ms.WriteInt((int)(msgBuffer.Length + 2)); // 获取经异或加密后的数据 msgBuffer = SecurityUtil.Xor(msgBuffer); // 获取 Crc 冗余校验码 ushort crc = Crc16.CalculateCrc16(msgBuffer); // 写入 Crc 冗余校验码 ms.WriteUShort(crc); // 写入 Xor 加密后的数据 ms.Write(msgBuffer, 0, msgBuffer.Length); } else { ms.WriteInt(0); } // 获取处理后的完整数据包 retBuffer = ms.ToArray(); } return(retBuffer); }
/// <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); }
/// <summary> /// 制作一个数据包,该数据包是符合传给服务器的格式的(包头+包体) /// 当前工程的格式是包头:包体长度,包体:压缩标志+CRC校验码+加密的真正数据(异或算法)(协议编码+协议内容) /// 把private改为public,配合本机模式本地测试用 /// </summary> /// <param name="data">真实数据</param> /// <returns></returns> public byte[] MakeDataPkg(byte[] data) { byte[] returnBuffer = null; data = SecurityUtil.XorAlgorithm(data); //1、加密 bool isCompress = data.Length > mCompressMinSize; //2、压缩 if (isCompress) { //开始压缩 data = ZlibHelper.CompressBytes(data); } ushort crc16 = Crc16.CalculateCrc16(data); //3、CRC校验 using (MemoryStreamUtil stream = new MemoryStreamUtil()) { stream.WriteUShort((ushort)(data.Length + 3)); //写包头,+3是因为多了一个bool,一个ushort,一共3字节 stream.WriteBool(isCompress); //写压缩标志 stream.WriteUShort(crc16); //写CRC stream.Write(data, 0, data.Length); //写加密后的真实数据 returnBuffer = stream.ToArray(); } Debug.Log("数据包构建完毕!"); return(returnBuffer); }
protected override void OnUpdate() { base.OnUpdate(); if (m_IsConnectedOk) { m_IsConnectedOk = false; if (OnConnectOK != null) { OnConnectOK(); } AppDebug.Log("连接成功"); } #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 (MMO_MemoryStream ms = new MMO_MemoryStream(buffer)) { isCompress = ms.ReadBool(); crc = ms.ReadUShort(); ms.Read(bufferNew, 0, bufferNew.Length); } //先crc 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 (MMO_MemoryStream ms = new MMO_MemoryStream(bufferNew)) { //协议编号 protoCode = ms.ReadUShort(); ms.Read(protoContent, 0, protoContent.Length); SocketDispatcher.Instance.Dispatch(protoCode, protoContent); } } else { break; } } else { break; } } } else { m_ReceiveCount = 0; break; } } #endregion }
/// <summary> /// 拆包 /// </summary> /// <param name="buff">缓存区数据</param> /// <param name="len">数据长度</param> /// <returns></returns> public List <TSocketMessage> UnpackData(byte[] buff, int len) { // 拷贝本次有效的字节 byte[] _b = new byte[len]; Array.Copy(buff, 0, _b, 0, _b.Length); buff = _b; if (this.LBuff.Count > 0) { // 拷贝之前遗留的字节 this.LBuff.AddRange(_b); buff = this.LBuff.ToArray(); this.LBuff.Clear(); this.LBuff = new List <byte>(2); } List <TSocketMessage> list = new List <TSocketMessage>(); // 存放 data 的 Crc 校验码 ushort crc = 0; try { // 获取实际数据包体 using (MMO_MemoryStream ms = new MMO_MemoryStream(buff)) { byte[] _buff; Label_00983: #region 包头读取 // 循环读取包头 // 判断本次解析的字节是否满足常量字节数 if (ms.Length - ms.Position < ConstLength) { _buff = ms.ReadBytes((int)(ms.Length - ms.Position)); this.LBuff.AddRange(_buff); return(list); } short head11 = ms.ReadShort(); short head22 = ms.ReadShort(); // 如果未找到包头,则将字节流从上一次读取的位置向后移动一字节 if (!(head1 == head11 && head2 == head22)) { long newPosition = ms.Seek(-3, SeekOrigin.Current); goto Label_00983; } #endregion // 数据类型 byte msgType = (byte)ms.ReadByte(); // 数据体长度 int offset = ms.ReadInt(); #region 包解析 // 剩余字节数大于本次需要读取的字节数 if (offset <= (ms.Length - ms.Position)) { crc = ms.ReadUShort(); _buff = ms.ReadBytes(offset - 2); int newCrc = Crc16.CalculateCrc16(_buff); if (newCrc == crc) { _buff = SecurityUtil.Xor(_buff); list.Add(new TSocketMessage(_buff, msgType)); } } // 剩余字节数刚好小于本次读取的字节数,先存起来,等待接受剩余字节数一起解析 else { _buff = ms.ReadBytes((int)(ms.Length - ms.Position)); this.LBuff.AddRange(_buff); } #endregion } } catch (Exception ex) { throw new Exception("数据读取错误:" + ex.Message); } return(list); }
/// <summary> 接收数据回调 </summary> /// <param name="ar"></param> private void ReceiveCallBack(IAsyncResult ar) { try { int len = m_Scoket.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) { //进行拆包 byte[] buffer = new byte[currMsgLen]; //将数据指针设置到包体位置 m_ReceiveMS.Position = 2; //把包体读到byte[]数组 m_ReceiveMS.Read(buffer, 0, currMsgLen); //======================= //异或后的数据 byte[] bufferNew = new byte[buffer.Length - 3]; bool isCompress = false; ushort crc = 0; using (MMO_MemoryStream ms = new MMO_MemoryStream(buffer)) { isCompress = ms.ReadBool(); crc = ms.ReadUShort(); ms.Read(bufferNew, 0, bufferNew.Length); } //1.crc校验 int newCrc = Crc16.CalculateCrc16(bufferNew); if (newCrc == crc) { //2.异或得到原始数据 bufferNew = SecurityUtil.Xor(bufferNew); if (isCompress) { bufferNew = ZlibHelper.DeCompressBytes(bufferNew); } ushort protoCode = 0; byte[] protoContent = new byte[bufferNew.Length - 2]; using (MMO_MemoryStream ms = new MMO_MemoryStream(bufferNew)) { //协议编号 protoCode = ms.ReadUShort(); //Console.WriteLine(protoContent.Length + " "+protoCode); ms.Read(protoContent, 0, protoContent.Length); EventDispatcher.Instance.Dispatcher(protoCode, m_Role, protoContent); } } else { Console.WriteLine("校验码不匹配"); break; } //=============处理剩余字节数组============== 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 { Console.WriteLine("客户端{0}断开连接", m_Scoket.RemoteEndPoint.ToString()); RoleMgr.Instance.AllRole.Remove(m_Role); } } catch { Console.WriteLine("客户端{0}断开连接......", m_Scoket.RemoteEndPoint.ToString()); RoleMgr.Instance.AllRole.Remove(m_Role); } }
/// <summary> /// 接收数据回调 /// </summary> /// <param name="ar"></param> private void ReceiveCallBack(IAsyncResult ar) { try { int len = m_Socket.EndReceive(ar); if (len > 0) { //已经接收到数据 //把接收到数据 写入缓冲数据流的尾部 m_ReceiveMS.Position = m_ReceiveMS.Length; //把指定长度的字节 写入数据流 m_ReceiveMS.Write(m_ReceiveBuffer, 0, len); //如果缓存数据流的长度>2 说明至少有个不完整的包过来了 //为什么这里是2 因为我们客户端封装数据包 用的ushort 长度就是2 if (m_ReceiveMS.Length > 2) { //进行循环 拆分数据包 while (true) { //把数据流指针位置放在0处 m_ReceiveMS.Position = 0; //currMsgLen = 包体的长度 int currMsgLen = m_ReceiveMS.ReadUShort(); //currFullMsgLen 总包的长度=包头长度+包体长度 int currFullMsgLen = 2 + currMsgLen; //如果数据流的长度>=整包的长度 说明至少收到了一个完整包 if (m_ReceiveMS.Length >= currFullMsgLen) { //至少收到一个完整包 //定义包体的byte[]数组 byte[] buffer = new byte[currMsgLen]; //把数据流指针放到2的位置 也就是包体的位置 m_ReceiveMS.Position = 2; //把包体读到byte[]数组 m_ReceiveMS.Read(buffer, 0, currMsgLen); //---------------------------------------------------------- //这是异或之后的数组 byte[] bufferNew = new byte[buffer.Length - 3]; bool isCompress = false; ushort crc = 0; using (MMO_MemoryStream ms = new MMO_MemoryStream(buffer)) { isCompress = ms.ReadBool(); crc = ms.ReadUShort(); ms.Read(bufferNew, 0, bufferNew.Length); } //校验Crc int newCrc = Crc16.CalculateCrc16(bufferNew); if (newCrc == crc)//本地Crc与数据包的进行校验 { //异或 得到原始数据 bufferNew = SecurityUtil.Xor(bufferNew); if (isCompress)//如果压缩了 { //进行解压 bufferNew = ZlibHelper.DeCompressBytes(bufferNew); } //协议编号 ushort protoCode = 0; //协议内容 byte[] protoContent = new byte[buffer.Length - 2]; using (MMO_MemoryStream ms = new MMO_MemoryStream(bufferNew)) { protoCode = ms.ReadUShort(); ms.Read(protoContent, 0, protoContent.Length); } EventDispatcher.Instance.Dispath(protoCode, m_Role, protoContent); } //==============处理剩余字节数组=================== //剩余字节长度 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 { //客户端断开连接 Console.WriteLine("客户端{0}断开连接1", m_Socket.RemoteEndPoint.ToString()); RoleMgr.Instance.AllRole.Remove(m_Role); } } catch (Exception ex) { //客户端断开连接 Console.WriteLine("客户端{0}断开连接2 原因{1}", m_Socket.RemoteEndPoint.ToString(), ex.Message); RoleMgr.Instance.AllRole.Remove(m_Role); } }
protected override void OnUpdate() { base.OnUpdate(); #region 从队列中获取数据 while (true) { //每帧读取5个数据 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; //读取协议编号 //ushort protoCode = 0; //数据包内容 //byte[] protoContent = new byte[buffer.Length - 2]; using (MMO_MemoryStream ms = new MMO_MemoryStream(buffer)) { isCompress = ms.ReadBool(); //传递过来的CRC crc = ms.ReadUShort(); ms.Read(bufferNew, 0, bufferNew.Length); } //计算CRC int newCrc = Crc16.CalculateCrc16(bufferNew); Debug.Log("CRC=" + crc); Debug.Log("NewCRC=" + newCrc); if (newCrc == crc) { //异或,得到原始数据 bufferNew = SecurityUtil.Xor(bufferNew); //解压缩 if (isCompress) { bufferNew = ZlibHelper.DeCompressBytes(bufferNew); } ushort protoCode = 0; byte[] protoContent = new byte[buffer.Length - 2]; //解析 using (MMO_MemoryStream ms = new MMO_MemoryStream(bufferNew)) { protoCode = ms.ReadUShort(); ms.Read(protoContent, 0, protoContent.Length); SocketDispatcher.Instance.Dispatch(protoCode, protoContent); } } else { break; } } else { break; } } } else { m_ReceiveCount = 0; break; } } #endregion }
/// <summary> /// 异步接受回调 /// </summary> /// <param name="ar"></param> private void ReceiveCallBack(IAsyncResult ar) { try { int len = m_Socket.EndReceive(ar); if (len > 0) { //将接受的数组缓存到缓存数据流的尾部 m_ReceiveMS.Position = m_ReceiveMS.Length; //byte[] 缓存到数据流中 m_ReceiveMS.Write(m_ReceiveBuffer, 0, len); //说明至少有一个不完整的包传了过来 if (m_ReceiveBuffer.Length > 2) { while (true) { //指针位置经过writey已经下移,要读的话需要归0 m_ReceiveMS.Position = 0; //读取包头包含的长度信息 ushort bodylen = m_ReceiveMS.ReadUShort(); Console.WriteLine(m_ReceiveMS.Position); //整个包大小 int fullLen = bodylen + 2; //说明已经有一个完整的包读取下来 if (m_ReceiveMS.Length >= bodylen + 2) { //读取包头 byte[] newBuffer = new byte[bodylen - 3]; bool isCompress = m_ReceiveMS.ReadBool(); ushort crc = m_ReceiveMS.ReadUShort(); m_ReceiveMS.Read(newBuffer, 0, bodylen - 3); //1..异或 newBuffer = SecurityUtil.Xor(newBuffer); //2.CRC1校验 ushort newCrc = Crc16.CalculateCrc16(newBuffer); if (newCrc != crc) { break; } if (isCompress) { //3.解压 newBuffer = ZlibHelper.DeCompressBytes(newBuffer); } using (MMO_MemoryStream ms = new MMO_MemoryStream(newBuffer)) { ushort protoCode = ms.ReadUShort(); byte[] protoContent = new byte[newBuffer.Length - 2]; ms.Read(protoContent, 0, protoContent.Length); //派发事件 EventDispatcher.Instance.Dispatc(protoCode, m_Role, protoContent); } //处理剩余的包 int remainingLen = (int)m_ReceiveMS.Length - fullLen; //--------- //重新写入数据流 //--------- if (remainingLen > 0) { //剩余数组缓冲 byte[] remianingBuffer = new byte[m_ReceiveMS.Length - fullLen]; //读取到剩余数组缓冲 m_ReceiveMS.Read(remianingBuffer, 0, remainingLen); //格式化数据流 m_ReceiveMS.Position = 0; m_ReceiveMS.SetLength(0); //重新写入数据流 m_ReceiveMS.Write(remianingBuffer, 0, remianingBuffer.Length); } else { //格式化数据流 m_ReceiveMS.Position = 0; m_ReceiveMS.SetLength(0); break; } } //包不完整 else { break; } } } ReceiveMsg(); } //客户端主动断开连接 else { Console.WriteLine(string.Format("客户端{0}主动断开连接", m_Socket.RemoteEndPoint)); RoleMgr.Instance.Roles.Remove(m_Role); } } //客户端进程结束 被迫断开连接 catch { Console.WriteLine(string.Format("客户端{0}被迫断开连接", m_Socket.RemoteEndPoint)); RoleMgr.Instance.Roles.Remove(m_Role); } }
internal void OnUpdate() { if (m_IsConnectedOk) { m_IsConnectedOk = false; OnConnectOK?.Invoke(); Debug.Log("连接成功"); } #region 从队列中获取数据 while (true) { if (m_ReceiveCount < GameEntry.Socket.MaxReceiveCount) { lock (m_ReceiveQueue) { if (m_ReceiveQueue.Count > 0) { m_ReceiveCount++; //得到队列中的数据包 byte[] buffer = m_ReceiveQueue.Dequeue(); //异或之后的数组 byte[] bufferNew = new byte[buffer.Length - 3]; bool isCompress = false; ushort crc = 0; MMO_MemoryStream ms1 = m_SocketReceiveMS; ms1.SetLength(0); ms1.Write(buffer, 0, buffer.Length); ms1.Position = 0; isCompress = ms1.ReadBool(); crc = ms1.ReadUShort(); ms1.Read(bufferNew, 0, bufferNew.Length); //using (MMO_MemoryStream ms = new MMO_MemoryStream(buffer)) //{ // isCompress = ms.ReadBool(); // crc = ms.ReadUShort(); // ms.Read(bufferNew, 0, bufferNew.Length); //} //先crc 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]; MMO_MemoryStream ms2 = m_SocketReceiveMS; ms2.SetLength(0); ms2.Write(bufferNew, 0, bufferNew.Length); ms2.Position = 0; protoCode = ms2.ReadUShort(); ms2.Read(protoContent, 0, protoContent.Length); GameEntry.Event.SocketEvent.Dispatch(protoCode, protoContent); //using (MMO_MemoryStream ms = new MMO_MemoryStream(bufferNew)) //{ // //协议编号 // protoCode = ms.ReadUShort(); // ms.Read(protoContent, 0, protoContent.Length); // GameEntry.Event.SocketEvent.Dispatch(protoCode, protoContent); //} } else { break; } ////测试,待删除,上述注释代码为加密之后的解读过程,为真正的代码 //using (MMO_MemoryStream ms = new MMO_MemoryStream(buffer)) //{ // //协议编号 // ushort protoCode = ms.ReadUShort(); // byte[] protoContent = new byte[buffer.Length - 2]; ; // ms.Read(protoContent, 0, protoContent.Length); // GameEntry.Event.SocketEvent.Dispatch(protoCode, protoContent); //} } else { break; } } } else { m_ReceiveCount = 0; break; } } CheckSendQueue(); #endregion }
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("链接断了。"); } }
// Update is called once per frame protected override void OnUpdate() { base.OnUpdate(); 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 (MMO_MemoryStream ms = new MMO_MemoryStream(buffer)) { isCompress = ms.ReadBool(); crc = ms.ReadUShort(); ms.Read(bufferNew, 0, bufferNew.Length); } //1.crc校验 int newCrc = Crc16.CalculateCrc16(bufferNew); if (newCrc == crc) { //2.异或得到原始数据 bufferNew = SecurityUtil.Xor(bufferNew); if (isCompress) { bufferNew = ZlibHelper.DeCompressBytes(bufferNew); } ushort protoCode = 0; byte[] protoContent = new byte[bufferNew.Length - 2]; using (MMO_MemoryStream ms = new MMO_MemoryStream(bufferNew)) { //协议编号 protoCode = ms.ReadUShort(); ms.Read(protoContent, 0, protoContent.Length); SocketDispatcher.Instance.Dispatcher(protoCode, protoContent); } } else { break; } } else { break; } } } else { m_ReceiveCount = 0; break; } } }
/// <summary> /// 接收数据回调 /// </summary> /// <param name="ar"></param> private void ReceiveCallBack(IAsyncResult ar) { try { int len = m_Socket.EndReceive(ar); if (len > 0) { //已经接收到数据 //把接收到的数据 写入缓冲数据流的尾部 m_ReceiveMs.Position = m_ReceiveMs.Length; //把指定长度的字节写入数据流 m_ReceiveMs.Write(m_ReceiveBuffer, 0, len); //byte[] buffer = m_ReceiveMs.ToArray(); //如果缓存数据流的长度 大于 2 说明至少有个不完整的包过来 //我们客户端封装数据包 用的ushort 长度就是2 if (m_ReceiveMs.Length > 2) { //循环拆分数据包 while (true) { //把数据流指针位置放在0处 m_ReceiveMs.Position = 0; //当前包体长度 int currMsgLen = m_ReceiveMs.ReadUShort(); //当前总包的长度 int currFullMsgLen = 2 + currMsgLen; //如果数据流长度大于或等于总包长度 说明至少收到一个完整包 if (m_ReceiveMs.Length >= currMsgLen) { //收到完整包 byte[] buffer = new byte[currMsgLen]; //把数据流指针放在包体位置 m_ReceiveMs.Position = 2; //把包体读取到byte数组中 m_ReceiveMs.Read(buffer, 0, currMsgLen); //============================================================ //异或之后的数组 byte[] bufferNew = new byte[buffer.Length - 3]; bool isCompress = false; ushort crc = 0; using (MMO_MemoryStream ms = new MMO_MemoryStream(buffer)) { isCompress = ms.ReadBool(); crc = ms.ReadUShort(); ms.Read(bufferNew, 0, bufferNew.Length); } //1、CRC 计算 ushort 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]; //这里的buffer就是我们拆分的数据包 using (MMO_MemoryStream ms2 = new MMO_MemoryStream(bufferNew)) { protoCode = ms2.ReadUShort(); ms2.Read(protoContent, 0, protoContent.Length); } //将接收的数据协议进行分发 EventDispatcher.Instance.Dispatch(protoCode, m_Role, protoContent); } //处理剩余字节长度 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; } } } //进行下一次接收数据包 m_Socket.BeginReceive(m_ReceiveBuffer, 0, m_ReceiveBuffer.Length, SocketFlags.None, ReceiveCallBack, m_Socket); } else { //说明客户端断开连接了 Console.WriteLine("客户端{0}断开连接了", m_Socket.RemoteEndPoint.ToString()); //将角色移除 RoleMgr.Instance.AllRole.Remove(m_Role); } } catch { //说明客户端断开连接了 Console.WriteLine("客户端{0}断开连接了", m_Socket.RemoteEndPoint.ToString()); //将角色移除 RoleMgr.Instance.AllRole.Remove(m_Role); } }
//========================================================== 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 }
// ----------------------- 收到消息 -------------------- private void ReceiveBack(IAsyncResult ar) { try { // 接收数据的回调 int len = m_socket.EndReceive(ar); Console.WriteLine("收到的长度:{0}", len); if (len > 0) { // 已经接收到了数据, 放在缓冲数据流的尾部 m_ReceiveMS.Position = m_ReceiveMS.Length; // 把指定长度的字节写入字节流 m_ReceiveMS.Write(m_ReceiveBuffer, 0, len); // 如果长度大于2,至少有个不完整的包过来了, 为什么是2, 因为封装数据包的时候用的是ushort, 他的长度是2 if (m_ReceiveMS.Length > 2) { while (true) { // 数据流指针放在0处 m_ReceiveMS.Position = 0; // 包体的长度, 因为封装的时候, 就把真实数据的长度长度保存在了这个里面 int bodyLength = m_ReceiveMS.ReadUShort(); // 总包的长度 = 包头长度+包体长度,整个包的长度,就是原来包体的长度,加上, 保存长度的ushort的长度 int allLength = 2 + bodyLength; // 说明至少收到了一个完整的包 if (m_ReceiveMS.Length >= allLength) { // 包含了协议id的, 整个协议内容 byte[] bufferBody = new byte[bodyLength]; // 流的位置转到2 m_ReceiveMS.Position = 2; // 把包体读到数组中 m_ReceiveMS.Read(bufferBody, 0, bodyLength); // -------------------------------- 开始解包 ----------------------------- // 拿到是否压缩, crc验证码的变量 bool isComress = false; ushort oldCrc = 0; byte[] newContent = new byte[bufferBody.Length - 3]; using (MMO_MemoryStream ms = new MMO_MemoryStream(bufferBody)) { isComress = ms.ReadBool(); oldCrc = ms.ReadUShort(); ms.Read(newContent, 0, newContent.Length); } // 开始和最新的crc比较 ushort newCrc = Crc16.CalculateCrc16(newContent); if (newCrc == oldCrc) { // 解开异或 newContent = SecurityUtil.Xor(newContent); // 解开压缩 if (isComress) { newContent = ZlibHelper.DeCompressBytes(newContent); } ushort protoCode = 0; byte[] realContent = new byte[newContent.Length]; using (MMO_MemoryStream ms = new MMO_MemoryStream(newContent)) { protoCode = ms.ReadUShort(); // 读取最终的结果 ms.Read(realContent, 0, realContent.Length); // ------------------ -------------- 结束解包 ----------------------------- EventDispatcher.Instance.Dispatch(protoCode, role, realContent); } } else { break; } //------------- 处理剩余字节数组 ----------------- int remainLen = (int)m_ReceiveMS.Length - allLength; // 说明有剩余字节 if (remainLen > 0) { // 把指针放在第一个包的尾部 m_ReceiveMS.Position = allLength; byte[] remainBuff = new byte[remainLen]; m_ReceiveMS.Read(remainBuff, 0, remainLen); // 清空数据流 m_ReceiveMS.Position = 0; m_ReceiveMS.SetLength(0); // 又重新写进流中 m_ReceiveMS.Write(remainBuff, 0, remainBuff.Length); remainBuff = null; } else { // 没有剩余字节 // 清空数据流 m_ReceiveMS.Position = 0; m_ReceiveMS.SetLength(0); break; } } else { break; // 没有收到完整包 } } } // 继续接受包 ReceiveMsg(); } else { // 说明客户端断开连接 Console.WriteLine("客户端{0}断开连接", m_socket.RemoteEndPoint.ToString()); RoleMgr.Instance.AllRole.Remove(role); } } catch (Exception) { // 说明客户端断开连接 Console.WriteLine("客户端{0}断开连接", m_socket.RemoteEndPoint.ToString()); RoleMgr.Instance.AllRole.Remove(role); } }
internal void OnUpdate() { if (m_IsConnectedOk) { m_IsConnectedOk = false; if (OnConnectOK != null) { OnConnectOK(); } } #region 从队列中获取数据 while (true) { if (m_ReceiveCount <= GameEntry.Socket.MaxReceiveCount) { 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; //待改 MMO_MemoryStream msl = m_SocketReceiveMS; msl.SetLength(0); msl.Write(buffer, 0, buffer.Length); msl.Position = 0; isCompress = msl.ReadBool(); crc = msl.ReadUShort(); msl.Read(bufferNew, 0, bufferNew.Length); //using (MMO_MemoryStream ms = new MMO_MemoryStream(buffer)) //{ // isCompress = ms.ReadBool(); // crc = ms.ReadUShort(); // ms.Read(bufferNew, 0, bufferNew.Length); //} //先crc 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 (MMO_MemoryStream ms = new MMO_MemoryStream(bufferNew)) { //协议编号 protoCode = ms.ReadUShort(); ms.Read(protoContent, 0, protoContent.Length); GameEntry.Event.SocketEvent.Dispatch(protoCode, protoContent); } } else { break; } } else { break; } } } else { m_ReceiveCount = 0; break; } } #endregion CheckSendQueue(); }
// Update is called once per frame void Update() { #region 从队列中获取数据 while (true) { if (m_ReceiveCount <= 5) { m_ReceiveCount++; lock (m_ReceiveQueue) { if (m_ReceiveQueue.Count > 0) { //buffer 包体(队列中的数据包) byte[] buffer = m_ReceiveQueue.Dequeue(); //这是异或之后的数组 byte[] bufferNew = new byte[buffer.Length - 3]; bool isCompress = false; ushort crc = 0; using (MMO_MemoryStream ms = new MMO_MemoryStream(buffer)) { isCompress = ms.ReadBool(); crc = ms.ReadUShort(); ms.Read(bufferNew, 0, bufferNew.Length); } //校验Crc int newCrc = Crc16.CalculateCrc16(bufferNew); Debug.Log("传递Crc=" + crc); Debug.Log("本地newCrc=" + newCrc); if (newCrc == crc)//本地Crc与数据包的进行校验 { //异或 得到原始数据 bufferNew = SecurityUtil.Xor(bufferNew); if (isCompress)//如果压缩了 { //进行解压 bufferNew = ZlibHelper.DeCompressBytes(bufferNew); } ushort protoCode = 0; byte[] protoContent = new byte[bufferNew.Length - 2]; using (MMO_MemoryStream ms = new MMO_MemoryStream(bufferNew)) { //读 协议编号 protoCode = ms.ReadUShort(); //读内容 ms.Read(protoContent, 0, protoContent.Length); //派发协议编号和内容 EventDispatcher.Instance.Dispath(protoCode, protoContent); } } else { break; } } else { break; } } } else { m_ReceiveCount = 0; break; } } #endregion }
/// <summary> /// 接收数据回调 /// </summary> /// <param name="ar"></param> private void ReceiveCallBack(IAsyncResult ar) { try { int len = Client.EndReceive(ar); if (len > 0) { //已经接收到数据 //把接收到数据 写入缓冲数据流的尾部 m_ReceiveMS.Position = m_ReceiveMS.Length; //把指定长度的字节 写入数据流 m_ReceiveMS.Write(m_ReceiveBuffer, 0, len); //如果缓存数据流的长度>2 说明至少有个不完整的包过来了 //为什么这里是2 因为我们客户端封装数据包 用的ushort 长度就是2 if (m_ReceiveMS.Length > 2) { //进行循环 拆分数据包 while (true) { //把数据流指针位置放在0处 m_ReceiveMS.Position = 0; //currMsgLen = 包体的长度 int currMsgLen = m_ReceiveMS.ReadUShort(); //currFullMsgLen 总包的长度=包头长度+包体长度 int currFullMsgLen = 2 + currMsgLen; //如果数据流的长度>=整包的长度 说明至少收到了一个完整包 if (m_ReceiveMS.Length >= currFullMsgLen) { //至少收到一个完整包 //定义包体的byte[]数组 byte[] buffer = new byte[currMsgLen]; //把数据流指针放到2的位置 也就是包体的位置 m_ReceiveMS.Position = 2; //把包体读到byte[]数组 m_ReceiveMS.Read(buffer, 0, currMsgLen); //=================================================== //异或之后的数组 byte[] bufferNew = new byte[buffer.Length - 3]; bool isCompress = false; ushort crc = 0; using (MMO_MemoryStream ms = new MMO_MemoryStream(buffer)) { isCompress = ms.ReadBool(); crc = ms.ReadUShort(); ms.Read(bufferNew, 0, bufferNew.Length); } //先crc 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[buffer.Length - 2]; using (MMO_MemoryStream ms = new MMO_MemoryStream(bufferNew)) { protoCode = ms.ReadUShort(); ms.Read(protoContent, 0, protoContent.Length); } EventDispatcher.Instance.Dispatch(protoCode, this, protoContent); Console.WriteLine("接收到消息开始转发"); //Console.WriteLine("接收到客户端发送过来的消息 "+protoCode); //if(protoCode == 1001) //{ // // 处理消息 // TestProto proto = TestProto.GetProto(protoContent); // Console.WriteLine(proto.msg); // TestProto2 p2 = new TestProto2(); // p2.msg = "我是服务器 这是我得消息"; // SendMsg(p2.ToArray()); //} } //==============处理剩余字节数组=================== //剩余字节长度 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 { //客户端断开连接 Console.WriteLine("客户端{0}断开连接", Client.RemoteEndPoint.ToString()); //m_Role.UpdateLastInWorldMap(); //WorldMapSceneMgr.Instance.RoleLeave(m_Role.RoleId, m_Role.LastInWorldMapId); //RoleMgr.Instance.AllRole.Remove(m_Role); } } catch (Exception ex) { //客户端断开连接 Console.WriteLine("客户端{0}断开连接", Client.RemoteEndPoint.ToString()); //m_Role.UpdateLastInWorldMap(); //WorldMapSceneMgr.Instance.RoleLeave(m_Role.RoleId, m_Role.LastInWorldMapId); //RoleMgr.Instance.AllRole.Remove(m_Role); } }
/// <summary> /// 模拟要点:解客户端数据包,同时向正式代码模拟发送服务端数据包 /// 41课以后包体结构更复杂,包体=协议编号+协议内容 /// 43课以后数据包完全体为:包体=压缩标志+CRC校验码+异或算法后的真实数据(协议编号+协议内容) /// </summary> /// <param name="dataPkg">本地向服务器传什么数据</param> /// <param name="isDIYReturnMsg">是否由客户端决定服务器返回什么数据,默认为false,就是由服务端通过逻辑处理后返回一个伪真实的数据,如果为true,就是一个由客户端决定的纯伪造的数据</param> /// <param name="returnPkg">希望服务器向本地传什么数据</param> public void ServerOperator(byte[] dataPkg, bool isDIYReturnPkg = false) { if (isDIYReturnPkg == true) //向客户端返回的是客户端指定的数据包,不必再做下列处理 { return; } mReceiveStream.Position = mReceiveStream.Length; mReceiveStream.Write(dataPkg, 0, dataPkg.Length); //数据写进内存,等待操作 mReceiveStream.Position = 0; int currentMsgLen = mReceiveStream.ReadUShort(); //包体长度 int currentFullLen = 2 + currentMsgLen; //包头+包体长度 if (mReceiveStream.Length >= currentFullLen) //接收的数据包大于一个完整包的长度,表示至少有一个完整包传过来了 { byte[] buffer = new byte[currentMsgLen]; //此buffer为数据包,包体内容 mReceiveStream.Position = 2; //把包头去掉,剩下包体 mReceiveStream.Read(buffer, 0, currentMsgLen); //把数据读到buffer中 #region 43课以后完整版数据包增加以下内容 ushort CRC = 0; //CRC校验码 bool isCompress = false; //压缩标志 byte[] realDataBuffer = new byte[buffer.Length - 3]; //刨除CRC和压缩标志,真正数据部分 using (MemoryStreamUtil stream = new MemoryStreamUtil(buffer)) { isCompress = stream.ReadBool(); //获取压缩标志 CRC = stream.ReadUShort(); //获取CRC校验码 stream.Read(realDataBuffer, 0, realDataBuffer.Length); } ushort newCRC = Crc16.CalculateCrc16(realDataBuffer); //开始校验CRC if (CRC == newCRC) //校验通过 { if (isCompress) { realDataBuffer = ZlibHelper.DeCompressBytes(realDataBuffer); //解压 } realDataBuffer = SecurityUtil.XorAlgorithm(realDataBuffer); //解密,此时realDataBuffer是可以操作的数据 } else { Debug.Log("server:CRC verify failed!"); return; } #endregion #region 41课以后服务器增加以下内容 ushort protoCode = 0; byte[] protoContent = new byte[realDataBuffer.Length - 2]; //可操作数据buffer减去协议编号部分 #endregion using (MemoryStreamUtil stream = new MemoryStreamUtil(realDataBuffer)) { protoCode = stream.ReadUShort(); stream.Read(protoContent, 0, protoContent.Length); SocketDispatcher.Instance.Dispatch(protoCode, protoContent); //EventDispatcherS.Instance.Dispatch(protoCode, null, protoContent); } //41课以后使用网络协议,增加此部分判断逻辑 //43课以后使用观察者模式 //此处作为模拟器不使用观察者模式,采用模拟数据的方式简易处理 /* * if (protoCode == Leo_ProtoCodeDefine.RoleOperation_Login) * { * Leo_ProtoTest test = Leo_ProtoTest.ToObject(protoContent); * Debug.Log("服务器解析协议成功,协议编号:" + protoCode); * Debug.Log("ID:" + test.ID); * Debug.Log("name:" + test.name); * Leo_ProtoTest testReturn = new Leo_ProtoTest(); * testReturn.protoCode = Leo_ProtoCodeDefine.RoleOperation_Login; * testReturn.ID = 2002; * testReturn.name = "return"; * testReturn.price = 2.22f; * byte[] returnBuffer = Leo_SocketManager.Instance.MakeDataPkg(testReturn.ToArray()); //模拟服务器向客户端返回一条协议数据 * } * */ //Leo_SocketDispatcher.Instance.Dispatch(protoCode, protoContent); } else { Debug.Log("服务器解析数据包错误!"); } //2020-06-25新增,一次接收结束后把stream里的内容清空,保证下次接收的内容是新的 mReceiveStream.Position = 0; mReceiveStream.SetLength(0); }
/// <summary> /// 检查接收到的数据包 /// </summary> public void OnReceiveDataDis() { #region 从队列中获取数据 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 (ServerMemoryStream ms = new ServerMemoryStream(buffer)) { isCompress = ms.ReadBool(); crc = ms.ReadUShort(); ms.Read(bufferNew, 0, bufferNew.Length); } //先crc 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 (ServerMemoryStream ms = new ServerMemoryStream(bufferNew)) { //协议编号 protoCode = ms.ReadUShort(); ms.Read(protoContent, 0, protoContent.Length); //交给观察者分配处理 CSObserver.Instance.Dispatch(protoCode, protoContent, this); } } } } } else { m_ReceiveCount = 0; OnReceiveDataDis(); } #endregion }