public static Role_ListTestProto GetProto(byte[] buffer, bool isChild = false) { Role_ListTestProto proto = new Role_ListTestProto(); MMO_MemoryStream ms = null; if (!isChild) { ms = GameEntry.Socket.SocketSendMS; } else { ms = GameEntry.Pool.DequeueClassObject <MMO_MemoryStream>(); } ms.SetLength(0); ms.Write(buffer, 0, buffer.Length); ms.Position = 0; proto.RoleType = ms.ReadInt(); int len_CurrRole = ms.ReadInt(); if (len_CurrRole > 0) { byte[] buff_CurrRole = new byte[len_CurrRole]; ms.Read(buff_CurrRole, 0, len_CurrRole); proto.CurrRole = Role_DataProto.GetProto(buff_CurrRole, true); } int len_RoleList = ms.ReadInt(); if (len_RoleList > 0) { proto.RoleList = new List <Role_DataProto>(); for (int i = 0; i < len_RoleList; i++) { int _len_RoleList = ms.ReadInt(); if (_len_RoleList > 0) { byte[] _buff_RoleList = new byte[_len_RoleList]; ms.Read(_buff_RoleList, 0, _len_RoleList); proto.RoleList.Add(Role_DataProto.GetProto(_buff_RoleList, true)); } } } if (isChild) { GameEntry.Pool.EnqueueClassObject(ms); } return(proto); }
/// <summary> /// 消息处理 在update 中执行 /// </summary> private void MessageProcessing() { while (true) { if (msgIndex < 5) { if (m_ReceiveQueue.Count > 0) { byte[] buffer = m_ReceiveQueue.Dequeue(); 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); SocketDispatcher.Instance.Dispatc(protoCode, protoContent); } } else { break; } } else { msgIndex = 0; break; } } }
/// <summary> /// 解析加密后的数据包得到原始数据包 /// </summary> /// <param name="dataCache"></param> public static byte[] DeMakeData(byte[] buffer) { // 拆包得到数据包 byte[] bufferNew = new byte[buffer.Length - 3]; bool IsComPressLen = false; ushort crc = 0; using (MMO_MemoryStream ms = new MMO_MemoryStream(buffer)) { //是否压缩 IsComPressLen = ms.ReadBool(); crc = ms.ReadUShort(); ms.Read(bufferNew, 0, bufferNew.Length); } //1、crc校验 ushort newCrc = CRC16.CalculateCrc16(bufferNew); if (newCrc == crc) { //2、异或后的原始数据包 bufferNew = SecurityUtil.Xor(bufferNew); if (IsComPressLen) { //3、解压缩 bufferNew是真实数据 bufferNew = ZlibHelper.deCompressBytes(bufferNew); } } return(bufferNew); }
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="ar"></param> private void ReceiveCallBack(IAsyncResult ar) { try { //结束挂起的异步接收,返回接收到的数据长度 int lenght = mClicentSocket.EndReceive(ar); //如果接收的数据大于0表示接受到数据 if (lenght > 0) { byte[] receiveData = new byte[lenght]; //将接收到的数据拷贝到receiveData中 Buffer.BlockCopy(ReceiveBuffer, 0, receiveData, 0, lenght); //存入数组(缓存) dataCache.AddRange(receiveData); //接收的数据 //如果缓存中存在数据全部拆包拆出来 while (dataCache.Count > 0) { //拆包拆出来的数据 byte[] data = Unpacking(ref dataCache); data = DeMakeData(data); //协议编号 ushort protoCode = 0; //保存,除去协议ushort的真正数据 byte[] protoConten = new byte[data.Length - 2]; using (MMO_MemoryStream ms = new MMO_MemoryStream(data)) { protoCode = ms.ReadUShort(); ms.Read(protoConten, 0, protoConten.Length); } EventDispatchet._instance.Dispatch(protoCode, mRole, protoConten); } //接收完数据启动异步接收,等待下一次接收 ReceiveMgs(); } else { //如果接收数据长度是0说明客户端断开连接 Console.WriteLine("客户端{0}已经断开连接", mClicentSocket.RemoteEndPoint.ToString()); RoleMgr._instance.AllRole.Remove(mRole); } } catch (Exception e) { //如果接收数据长度是0说明客户端断开连接 Console.WriteLine("客户端{0}已经断开连接", mClicentSocket.RemoteEndPoint.ToString()); Console.WriteLine("客户端{0}已经断开连接", e.Message); RoleMgr._instance.AllRole.Remove(mRole); } }
public static Role_ListTestProto GetProto(MMO_MemoryStream ms, byte[] buffer) { Role_ListTestProto proto = new Role_ListTestProto(); ms.SetLength(0); ms.Write(buffer, 0, buffer.Length); ms.Position = 0; proto.RoleType = ms.ReadInt(); int len_CurrRole = ms.ReadInt(); if (len_CurrRole > 0) { byte[] buff_CurrRole = new byte[len_CurrRole]; ms.Read(buff_CurrRole, 0, len_CurrRole); proto.CurrRole = Role_DataProto.GetProto(new MMO_MemoryStream(), buff_CurrRole); } int len_RoleList = ms.ReadInt(); if (len_RoleList > 0) { proto.RoleList = new List <Role_DataProto>(); for (int i = 0; i < len_RoleList; i++) { int _len_RoleList = ms.ReadInt(); if (_len_RoleList > 0) { byte[] _buff_RoleList = new byte[_len_RoleList]; ms.Read(_buff_RoleList, 0, _len_RoleList); proto.RoleList.Add(Role_DataProto.GetProto(new MMO_MemoryStream(), _buff_RoleList)); } } } return(proto); }
/// <summary> /// 接收数据回调 /// </summary> /// <param name="ar"></param> 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 说明至少有个不完整的包过来了 //为什么这里是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); 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())); } }
/// <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; //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); } }
/// <summary> /// 接收数据回调函数 /// </summary> /// <param name="ar"></param> 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); //假设只有一条消息,这个就是我们收到的消息 //byte[] buffer = m_ReceiveMS.ToArray(); //Console.WriteLine("buffer=" + buffer.Length); //如果缓存数据流的长度>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); //将数据包压入队列 lock (m_ReceiveQueue) { m_ReceiveQueue.Enqueue(buffer); } //buffer这个byte[]数组就是包体 也就是我们要的数据 //using (MMO_MemoryStream ms2 = new MMO_MemoryStream(buffer)) //{ // string msg = ms2.ReadUTF8String(); // Console.WriteLine(msg); //} //=============处理剩余字节数组数据================= //剩余字节长度 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 (Exception ex) { //客户端断开连接 Debug.Log(string.Format("客户端{0}断开连接", m_Client.RemoteEndPoint.ToString())); } }
// 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_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) { //进行拆包 byte[] buffer = new byte[currMsgLen]; //将数据指针设置到包体位置 m_ReceiveMS.Position = 2; //把包体读到byte[]数组 m_ReceiveMS.Read(buffer, 0, currMsgLen); lock (m_ReceiveQueue) { //buffer就是服务端发来的一条完整数据 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())); } }
/// <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); } }
// 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 }
//接收数据的回调 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,说明有至少有两个不完整的包发过来了 //为什么是2,因为 客户端封装的数据包用的是ushort 长度就是2 if (m_ReceiveMS.Length > 2) { //进行循环,拆包 while (true) { //把数据流指针位置放0处 m_ReceiveMS.Position = 0; //curMsgLen =包体的长度 int curMsgLen = m_ReceiveMS.ReadUShort(); //总包的长度 int curFullMsgLen = 2 + curMsgLen; //如果数据流的长度>=整体的长度 说明至少收到了一个完整包 if (m_ReceiveMS.Length >= curFullMsgLen) { //至少收到一个完整包 //定义包体的byte[]数组 byte[] buffer = new byte[curMsgLen]; //把数据流指针放到2的位置,也就是包体开头的位置 m_ReceiveMS.Position = 2; //把包体读到byte[]数组 m_ReceiveMS.Read(buffer, 0, curMsgLen); lock (m_ReceiveQueue) { m_ReceiveQueue.Enqueue(buffer); } //---------------------处理剩余字节数组------------------------------ int remainLen = (int)m_ReceiveMS.Length - curFullMsgLen; if (remainLen > 0)//如果有剩余字节 { //把指针放在第一个包的尾部 m_ReceiveMS.Position = curFullMsgLen; //定义剩余字节数组 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 //len=0 { //服务器断开连接 Debug.Log(string.Format("服务器{0}断开连接1", m_Client.RemoteEndPoint.ToString())); } } catch { //服务器断开连接 Debug.Log(string.Format("服务器{0}断开连接2", m_Client.RemoteEndPoint.ToString())); } }
// ----------------------- 收到消息 -------------------- 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; 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 }
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; //把指定长度的字节 写入数据流 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); } }
/// <summary> /// 接收数据回调 /// </summary> /// <param name="ar"></param> private void ReceiveCallBack(IAsyncResult ar) { try { int len = m_Socket.EndReceive(ar); if (len > 0) { //已经接收到数据 //Console.WriteLine($"{DateTime.Now}:{DateTime.Now.Millisecond} 接收到数据"); //把接收到数据 写入缓冲数据流的尾部 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 = 包体的长度 m_ReceiveMS.Read(out ushort currMsgLen); //currFullMsgLen 总包的长度=包头长度+包体长度 int currFullMsgLen = 2 + currMsgLen; //如果数据流的长度>=整包的长度 说明至少收到了一个完整包 if (m_ReceiveMS.Length >= currFullMsgLen) { //至少收到一个完整包 //把数据流指针放到2的位置 也就是包体的位置 m_ReceiveMS.Position = 2; //定义包体的byte[]数组 byte[] buffer = new byte[currMsgLen]; //把包体读到byte[]数组 m_ReceiveMS.Read(buffer, 0, currMsgLen); //=================================================== //协议编号 //BaseServer.ReceiveQueue.Enqueue(buffer); var protoCodeArr = new byte[2]; Array.Copy(buffer, protoCodeArr, protoCodeArr.Length); //异或之后的数组 short protoCode = BitConverter.ToInt16(protoCodeArr, 0); ProcessMessage(protoCode, buffer); //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; } } } //进行下一次接收数据包 ReceiveMsg(); } else { //客户端断开连接 Loger.Debug($"客户端{m_Socket.RemoteEndPoint.ToString()}断开连接"); } } catch (Exception ex) { //客户端断开连接 Loger.Debug($"客户端{m_Socket.RemoteEndPoint.ToString()}断开连接 原因{1}", ex); } }
/// <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); } }
/// <summary> /// 接收数据回调 /// </summary> /// <param name="ar"></param> 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 if (m_ReceiveMs.Length > 2)//至少有一个不完整的包 { while (true) { m_ReceiveMs.Position = 0; int currMsgLen = m_ReceiveMs.ReadUShort(); int currFullMsgLen = currMsgLen + 2; //数据流的长度>=整个包的长度 if (m_ReceiveMs.Length >= currFullMsgLen)//至少有一个完整包 { byte[] buffer = new byte[currMsgLen]; //把数据流的指针放到包体的位置 m_ReceiveMs.Position = 2; m_ReceiveMs.Read(buffer, 0, currMsgLen); lock (m_ReceiveQueue) { m_ReceiveQueue.Enqueue(buffer); } //==============处理剩余字节=============== int remainByteLen = (int)m_ReceiveMs.Length - currFullMsgLen; //剩余字节长度 if (remainByteLen > 0) //如果有剩余字节 { byte[] remainBuffer = new byte[remainByteLen]; m_ReceiveMs.Position = currFullMsgLen; m_ReceiveMs.Read(remainBuffer, 0, remainByteLen); //清空数据流 m_ReceiveMs.Position = 0; m_ReceiveMs.SetLength(0); //把剩余数据重新写入数据流 m_ReceiveMs.Write(remainBuffer, 0, remainByteLen); 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())); } }
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 }
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(); }
/// <summary> /// 从ms获取指定的字节数据 /// </summary> /// <param name="ms"></param> /// <param name="len"></param> /// <returns></returns> public byte[] GetByteArray(MMO_MemoryStream ms, int len) { byte[] buffer = new byte[len]; ms.Read(buffer, 0, len); return(buffer); }
/// <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(); //整个包大小 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); } Debug.Log(newCrc); lock (m_ReceiveQueue) { m_ReceiveQueue.Enqueue(newBuffer); } //处理剩余的包 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 { Debug.Log(string.Format("服务器{0}主动断开连接", m_Socket.RemoteEndPoint)); } } //客户端进程结束 被迫断开连接 catch { Console.WriteLine(string.Format("服务器{0}被迫断开连接", m_Socket.RemoteEndPoint)); } }