/// <summary> /// 制作完整的数据包(包头+包体) /// </summary> /// <param name="_data"></param> /// <returns></returns> private byte[] MakeAllData(byte[] _data) { byte[] retBuffer = null; using (MMOMemoryStream ms = new MMOMemoryStream()) { //ushort占两个字节,作为包头的长度 //将长度转换成byte,写入数据流中 ms.WriteUshort((ushort)_data.Length); //将数据写入数据流 ms.Write(_data, 0, _data.Length); //读取 retBuffer = ms.ToArray(); } return(retBuffer); }
/// <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); //拆包 //因为包头占有两个字节 if (m_ReceiveMS.Length > 2) { //循环拆包 while (true) { //定位在数据包最开始的位置 m_ReceiveMS.Position = 0; //获取包体的长度(就是包头的值) int curMsgLen = m_ReceiveMS.ReadUshort(); //读取整个数据包 int curAllMsgLen = 2 + curMsgLen; //数据流的长度大于整个数据包的长度时,说明数据完整 if (m_ReceiveMS.Length >= curAllMsgLen) { //定义一个包体的byte[]数组 byte[] buffer = new byte[curMsgLen]; //定位在2的位置(包体开始的位置) m_ReceiveMS.Position = 2; //Read从流中读取,长度为包体的长度 m_ReceiveMS.Read(buffer, 0, curMsgLen); //buffer是最终读取的数据 using (MMOMemoryStream ms = new MMOMemoryStream(buffer)) { string data = ms.ReadUTF8String(); Console.WriteLine(data); } //==============处理剩余字节============== //剩余字节的长度 int remainLen = (int)m_ReceiveMS.Length - curAllMsgLen; //有剩余的字节长度 if (remainLen > 0) { //设定在上一个数据包的尾部 m_ReceiveMS.Position = curAllMsgLen; //剩余的字节数组 byte[] remainBuffer = new byte[remainLen]; //将剩余的字节从流中读取 m_ReceiveMS.Read(remainBuffer, 0, remainLen); //清空数据流 m_ReceiveMS.Position = 0; m_ReceiveMS.SetLength(0); //重新写入数据流 m_ReceiveMS.Write(remainBuffer, 0, remainLen); //剩余空间不需要使用,应当释放 remainBuffer = null; } //无剩余的字节长度 else { //清空数据流 m_ReceiveMS.Position = 0; m_ReceiveMS.SetLength(0); break; } } //数据不完整,不拆包,等待下次数据写入 else { break; } } } //进行下一次数据包的接收 ReceiveMessage(); } else { Console.WriteLine("客户端{0}断开连接", m_Socket.RemoteEndPoint.ToString()); //集合中应当移除关闭连接的role RoleManager.Instance.AllRole.Remove(m_Role); Console.WriteLine("当前角色集合的长度为:{0}", RoleManager.Instance.AllRole.Count); } } catch (Exception ex) { Console.WriteLine("客户端{0}断开连接", m_Socket.RemoteEndPoint.ToString()); //集合中应当移除关闭连接的role RoleManager.Instance.AllRole.Remove(m_Role); Console.WriteLine("当前角色集合的长度为:{0}", RoleManager.Instance.AllRole.Count); } }