コード例 #1
0
        /// <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);
        }
コード例 #2
0
        /// <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);
            }
        }