Beispiel #1
0
        /// <summary>
        /// 读取一个结构体变量
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public T ReadStruct <T>()
        {
            Type anytype = typeof(T);
            int  rawsize = Marshal.SizeOf(anytype);

            if ((m_Index + rawsize) > m_Size)
            {
                return(default(T));
            }

            var buff = DogBuffer.GetFromPool4K();

            System.Buffer.BlockCopy(m_Data, (int)m_Index, buff.Bytes, 0, rawsize);
            m_Index += rawsize;

            GCHandle hObject = GCHandle.Alloc(buff.Bytes, GCHandleType.Pinned);
            IntPtr   pObject = hObject.AddrOfPinnedObject();

            try
            {
                return((T)Marshal.PtrToStructure(pObject, anytype));
            }
            finally
            {
                if (hObject.IsAllocated)
                {
                    hObject.Free();
                }
                buff.Release();
            }
        }
Beispiel #2
0
 /// <summary>
 /// 数据包写入器
 /// </summary>
 /// <param name="codeId">消息报的id</param>
 private PacketWriter(ushort codeId)
 {
     buffer = DogBuffer.GetFromPool32K();
     //  先预留2位用于存放消息id
     buffer.Length = ReceiveQueue.PacketLengthSize;
     Write(codeId);
 }
Beispiel #3
0
        /// <summary>
        /// 收到Socket数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void OnSocketRecv(object sender, SocketRecvEventArgs <Session> e)
        {
            var session = e.Session.Data;

            session.RQ.Enqueue(e.Buffer.Bytes, 0, e.Buffer.Length);

            var packetlen = session.RQ.GetPacketLength();

            while (packetlen >= session.RQ.Length)
            {
                var dogBuffer = new DogBuffer();
                session.RQ.Dequeue(dogBuffer.Bytes, 0, packetlen);

                var reader = new PacketReader();
                reader.SetBuffer(dogBuffer);

                var pid     = reader.GetPacketID();
                var handler = packetHandlersManager.GetHandler(pid);
                if (handler == null)
                {
                    Logs.Error("未知消息ID {0}", pid);
                }
                else
                {
                    //  网络的消息包都会压入任务队列里等待执行
                    taskManager.AppendTask(session, handler, reader);
                }

                packetlen = session.RQ.GetPacketLength();
            }
        }
Beispiel #4
0
        /// <summary>
        /// 从缓冲池里分配一个消息包
        /// </summary>
        /// <param name="buffer"></param>
        /// <returns></returns>
        public static PacketReader AcquireContent(DogBuffer buffer)
        {
            var ret = s_pool.AcquireContent();

            ret.SetBuffer(buffer);
            return(ret);
        }
Beispiel #5
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="buffer"></param>
 public void SetBuffer(DogBuffer buffer)
 {
     m_Data   = buffer.Bytes;
     m_Size   = buffer.Length;
     m_Index  = ReceiveQueue.PacketLengthSize + 2;   // 包头的长度和消息码长度
     m_buffer = buffer;
 }
Beispiel #6
0
 /// <summary>
 /// 释放资源
 /// </summary>
 public void Dispose()
 {
     if (m_buffer != null)
     {
         var t = m_buffer;
         m_buffer = null;
         t.Release();
     }
 }
Beispiel #7
0
        /// <summary>
        /// 设置网络消息码
        /// </summary>
        /// <param name="codeId"></param>
        public void SetNetCode(ushort codeId)
        {
            if (buffer != null)
            {
                buffer.Release();
            }

            buffer = DogBuffer.GetFromPool32K();
            //  先预留2位用于存放消息id
            buffer.Length = ReceiveQueue.PacketLengthSize;
            Write(codeId);
        }
Beispiel #8
0
        /// <summary>
        /// 收到Socket数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void OnSocketRecv(object sender, SocketRecvEventArgs <Session> e)
        {
            var session = e.Session.Data;

            session.RQ.Enqueue(e.Buffer.Bytes, 0, e.Buffer.Length);

            var packetlen = session.RQ.GetPacketLength();

            while (packetlen >= session.RQ.Length)
            {
                var dogBuffer = new DogBuffer();
                session.RQ.Dequeue(dogBuffer.Bytes, 0, packetlen);

                var reader = new PacketReader();
                reader.SetBuffer(dogBuffer);

                /*
                 * var pid = (OpCode)reader.GetPacketID();
                 *
                 * switch (pid)
                 * {
                 *  case OpCode.Login:
                 *      OnLogin(session, reader);
                 *      break;
                 *  case OpCode.SendMessage:
                 *      OnSendMessage(session, reader);
                 *      break;
                 *  case OpCode.SendPriviteMessage:
                 *      OnSendPrivateMessage(session, reader);
                 *      break;
                 *  default:
                 *      Logs.Error("未知消息ID {0}", (int)pid);
                 *      break;
                 * }
                 */

                var pid     = reader.GetPacketID();
                var handler = packetHandlersManager.GetHandler(pid);
                if (handler == null)
                {
                    Logs.Error("未知消息ID {0}", pid);
                }
                else
                {
                    handler.OnReceive(session, reader);
                }

                packetlen = session.RQ.GetPacketLength();
            }
        }
Beispiel #9
0
        public void TestSize()
        {
            var _4Kbuf = DogBuffer.GetFromPool4K();

            Assert.IsNotNull(_4Kbuf);
            Assert.AreEqual(_4Kbuf.Bytes.Length, 1024 * 4);
            Assert.AreEqual(_4Kbuf.Length, 0);

            var _32kbuf = DogBuffer.GetFromPool32K();

            Assert.IsNotNull(_32kbuf);
            Assert.AreEqual(_32kbuf.Bytes.Length, 1024 * 32);
            Assert.AreEqual(_32kbuf.Length, 0);
        }
Beispiel #10
0
        public void TestRelease32K()
        {
            var firstFree = Get32KbufferFree();

            var buf    = DogBuffer.GetFromPool32K();
            var 分配后的数量 = Get32KbufferFree();

            Assert.AreEqual(firstFree - 1, 分配后的数量);

            buf.Release();
            var 释放缓冲区后的数量 = Get32KbufferFree();

            Assert.AreEqual(firstFree, 释放缓冲区后的数量);

            //  测试重复释放会不会有问题
            buf.Release();
            释放缓冲区后的数量 = Get32KbufferFree();
            Assert.AreEqual(firstFree, 释放缓冲区后的数量);
        }
Beispiel #11
0
        public void BaseTest()
        {
            var manager = new PacketHandlersBase();
            var pr      = new PacketReaderModule();

            new RegisterNetMethod(manager).Register(new ILogicModule[] { pr });

            Assert.IsNotNull(manager.Handlers[1], "方法没注册到消息管理器里");

            manager.Handlers[1].OnReceive(new NetState(), new PacketReader(DogBuffer.GetFromPool32K()));
            Assert.IsTrue(pr.IsTouchOnReadTest);

            Assert.IsNotNull(manager.Handlers[2], "包读取方法没注册到消息管理器");
            manager.Handlers[2].OnReceive(new NetState(), new PacketReader(DogBuffer.GetFromPool32K()));
            Assert.IsTrue(pr.IsTouchPackageReader);

            Assert.IsNotNull(manager.Handlers[3], "简单读取方法没注册到消息管理器");
            manager.Handlers[3].OnReceive(new NetState(), new PacketReader(DogBuffer.GetFromPool32K()));
            Assert.IsTrue(pr.IsTouchSimpleMethod);
        }
Beispiel #12
0
        public void TestUpdateCapacity()
        {
            var buf = DogBuffer.GetFromPool4K();

            Assert.AreEqual(buf.Bytes.Length, 1024 * 4);
            Assert.AreEqual(buf.Length, 0);

            buf.Bytes[0]            = 1;
            buf.Bytes[1]            = 2;
            buf.Bytes[1024 * 4 - 1] = 255;

            var b = buf.Bytes;

            buf.UpdateCapacity();
            //  扩容后对象引用会不一样了
            Assert.AreNotSame(buf.Bytes, b);
            Assert.AreEqual(buf.Bytes.Length, 1024 * 8);

            //  验证数据扩容后是否正确
            Assert.AreEqual(buf.Bytes[0], 1);
            Assert.AreEqual(buf.Bytes[1], 2);
            Assert.AreEqual(buf.Bytes[1024 * 4 - 1], 255);
        }
Beispiel #13
0
        public void Test重复引用对象()
        {
            var firstFree = Get4KbufferFree();

            var buf    = DogBuffer.GetFromPool4K();
            var 分配后的数量 = Get4KbufferFree();

            Assert.AreEqual(firstFree - 1, 分配后的数量);
            buf.Use();

            buf.Release();  // 只释放一个引用
            var 释放缓冲区后的数量 = Get4KbufferFree();

            Assert.AreEqual(分配后的数量, 释放缓冲区后的数量);

            buf.Release();
            释放缓冲区后的数量 = Get4KbufferFree();
            Assert.AreEqual(firstFree, 释放缓冲区后的数量);

            buf.Release();
            释放缓冲区后的数量 = Get4KbufferFree();
            Assert.AreEqual(firstFree, 释放缓冲区后的数量);
        }
Beispiel #14
0
        /// <summary>
        /// 收到Socket数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void OnSocketRecv(object sender, SocketRecvEventArgs<Session> e)
        {
            lock (sessions)
            {
                var session = e.Session.Data;
                DogBuffer buf;
                if (e.Buffer.Length > 1024*4)
                {
                    buf = DogBuffer.GetFromPool32K();
                }
                else
                {
                    buf = DogBuffer.GetFromPool4K();
                }

                Array.Copy(e.Buffer.Bytes, buf.Bytes, e.Buffer.Length);
                buf.Length = e.Buffer.Length;
                session.Client.SendPackage(buf);
                buf.Release();

                recvPackageCount++;
                recvPackageLength += e.Buffer.Length;
            }
        }
Beispiel #15
0
        /// <summary>
        /// 收到网络消息包
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnSocketRecv(object sender, SocketRecvEventArgs <NetState> e)
        {
            var netState = e.Session.Data;

            netState.ReceiveBuffer.Enqueue(e.Buffer.Bytes, 0, e.Buffer.Length);
            if (netState.ReceiveBuffer.Length > MaxPackageSize)
            {
                //  缓冲区过多,一定发送了某种异常情况
                Logs.Error("client recv buff is full.");
                netState.NetSocket.CloseSocket();
                return;
            }

            while (netState.ReceiveBuffer.Length > 2)   // 大于包头长度才具备解析的需求
            {
                var len = netState.ReceiveBuffer.GetPacketLength();
                if (len == 0)
                {
                    Logs.Error("get package len is zero.");
                    netState.NetSocket.CloseSocket();
                    return;
                }

                if (len < 4)
                {
                    Logs.Error("get package len is min 4.");
                    netState.NetSocket.CloseSocket();
                    return;
                }

                if (len > MaxPackageSize)
                {
                    Logs.Error("get package len is error. size:{0}", len);
                    netState.NetSocket.CloseSocket();
                    return;
                }

                if (len <= netState.ReceiveBuffer.Length)
                {
                    DogBuffer readBuffer;
                    if (len < 1024 * 4)
                    {
                        readBuffer = DogBuffer.GetFromPool4K();
                    }
                    else
                    {
                        readBuffer = DogBuffer.GetFromPool32K();
                    }

                    var get = netState.ReceiveBuffer.Dequeue(readBuffer.Bytes, 0, len);
                    if (get == len)
                    {
                        readBuffer.Length = len;

                        var packageReader = PacketReader.AcquireContent(readBuffer);
                        var packageId     = packageReader.GetPacketID();
                        //Debug.Write("msgId = " + packageId.ToString());

                        var packetHandler = PacketHandlersManger.GetHandler(packageId);
                        if (packetHandler != null)
                        {
                            //  加入网络消息处理
                            if (_useManyTaskThread)
                            {
                                switch (packetHandler.TaskType)
                                {
                                case TaskType.Low:
                                    lowTask.AppendTask(netState, packetHandler, packageReader);
                                    break;

                                case TaskType.Assist:
                                    Logs.Debug("assist task.");
                                    assistTask.AppendTask(netState, packetHandler, packageReader);
                                    break;

                                default:
                                    mainTask.AppendTask(netState, packetHandler, packageReader);
                                    break;
                                }
                            }
                            else
                            {
                                mainTask.AppendTask(netState, packetHandler, packageReader);
                            }
                        }
                        else
                        {
                            Logs.Error("unknow packetid. code={0}", packageId);
                            netState.ErrorCount++;
                            if (netState.ErrorCount >= 10)
                            {
                                //  错误达到极大值,则关闭连接
                                Logs.Error("ip {0} error count max.", netState.GetIP());
                                netState.NetSocket.CloseSocket();
                            }
                        }
                    }
                    continue;
                }
                break;
            }
        }
        void NetSocket_SocketRecv(object sender, SocketRecvEventArgs <NetState> e)
        {
            var netState = e.Session.Data;

            netState.ReceiveBuffer.Enqueue(e.Buffer.Bytes, 0, e.Buffer.Length);

            if (netState.ReceiveBuffer.Length > MaxPackageSize)
            {
                //  缓冲区过多,一定发送了某种异常情况
                Logs.Error("client recv buff is full.");
                netState.NetSocket.CloseSocket();
                return;
            }

            while (netState.ReceiveBuffer.Length > 2)
            {
                var len = netState.ReceiveBuffer.GetPacketLength();
                if (len == 0)
                {
                    Logs.Error("get package len is zero.");
                    netState.NetSocket.CloseSocket();
                    return;
                }

                if (len < 4)
                {
                    Logs.Error("package is min 4.");
                    netState.NetSocket.CloseSocket();
                    return;
                }


                if (len > MaxPackageSize)
                {
                    Logs.Error("get package len is error. size:{0}", len);
                    netState.NetSocket.CloseSocket();
                    return;
                }

                IsWaitCheckOnline = false;

                if (len <= netState.ReceiveBuffer.Length)
                {
                    DogBuffer readBuffer;
                    if (len < 1024 * 4)
                    {
                        readBuffer = DogBuffer.GetFromPool4K();
                    }
                    else
                    {
                        readBuffer = DogBuffer.GetFromPool32K();
                    }

                    if (len >= readBuffer.Bytes.Length)
                    {
                        readBuffer.UpdateCapacity(len);
                    }

                    var get = netState.ReceiveBuffer.Dequeue(readBuffer.Bytes, 0, len);
                    if (get == len)
                    {
                        readBuffer.Length = len;

                        var    packageReader = PacketReader.AcquireContent(readBuffer);
                        ushort id            = packageReader.GetPacketID();
                        Logs.Debug("msgid= {0}", id);

                        var packetHandler = PacketHandlersManger.GetHandler(id);
                        if (packetHandler != null)
                        {
                            //  加入网络消息处理
                            TaskManager.AppendTask(netState, packetHandler, packageReader);
                        }
                        else
                        {
                            Logs.Error("unknow packetid. code={0}", id);
                        }
                    }

                    continue;
                }

                break;
            }
        }
Beispiel #17
0
        /// <summary>
        /// 收到Socket数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void OnSocketRecv(object sender, SocketRecvEventArgs <Session> e)
        {
            var session = e.Session.Data;

            session.RQ.Enqueue(e.Buffer.Bytes, 0, e.Buffer.Length);

            var packetlen = session.RQ.GetPacketLength();

            if (packetlen > 1024 * 64)
            {
                session.Client.CloseSocket();
                return;
            }

            while (packetlen >= session.RQ.Length)
            {
                var dogBuffer = new DogBuffer();
                session.RQ.Dequeue(dogBuffer.Bytes, 0, packetlen);

                var reader = new PacketReader();
                reader.SetBuffer(dogBuffer);

                var pid = (OpCode)reader.GetPacketID();

                switch (pid)
                {
                case OpCode.Login:
                {
                    var userName = reader.ReadUTF8String();
                    var pwd      = reader.ReadUTF8String();

                    if (string.IsNullOrEmpty(userName))
                    {
                        Logs.Error("连接的用户名是空");
                        session.Client.CloseSocket();
                    }

                    if (pwd != "123")
                    {
                        Logs.Error("用户名 {0} 速度的密码错误", userName);
                        var writer = new PacketWriter();
                        writer.SetNetCode((ushort)OpCode.LoginResult);
                        writer.Write(1);     //  0表示登录成功 1表示密码错误
                        session.Client.SendPackage(writer.GetBuffer());
                        return;
                    }

                    //  如果玩家之前登录过,则把之前的客户端踢下线
                    var exists = sessions.FirstOrDefault(o => o.Name == userName);
                    if (exists != null)
                    {
                        exists.IsLogin = false;
                        sessions.Remove(exists);
                        exists.Client.CloseSocket();
                    }

                    //  登录完成
                    session.IsLogin = true;
                    nologinSessions.Remove(session);
                    sessions.Add(session);

                    session.Name = userName;
                    session.Pwd  = pwd;
                    var writer2 = new PacketWriter();
                    writer2.SetNetCode((ushort)OpCode.LoginResult);
                    writer2.Write(0);     //  0表示登录成功 1表示密码错误
                    session.Client.SendPackage(writer2.GetBuffer());
                }
                break;

                case OpCode.SendMessage:
                {
                    var message = reader.ReadUTF8String();
                    if (string.IsNullOrEmpty(message))
                    {
                        //  空消息
                        return;
                    }

                    //  广播给所有在线的用户
                    var writer = new PacketWriter();
                    writer.SetNetCode((ushort)OpCode.RecvMessage);
                    foreach (var ss in sessions)
                    {
                        ss.Client.SendPackage(writer.GetBuffer());
                    }
                }
                break;

                case OpCode.SendPriviteMessage:
                {
                    var userName = reader.ReadUTF8String();
                    var message  = reader.ReadUTF8String();

                    if (message == null)
                    {
                        return;
                    }

                    var target = sessions.FirstOrDefault(o => o.Name == userName);
                    if (target == null)
                    {
                        return;
                    }

                    var writer = new PacketWriter();
                    writer.SetNetCode((ushort)OpCode.RecvPrivateMessage);
                    writer.WriteUTF8Null(session.Name);
                    writer.WriteUTF8Null(message);

                    target.Client.SendPackage(writer.GetBuffer());
                }
                break;

                default:
                    Logs.Error("未知消息ID {0}", (int)pid);
                    break;
                }


                packetlen = session.RQ.GetPacketLength();
            }
        }
Beispiel #18
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="buffer"></param>
 public PacketReader(DogBuffer buffer)
 {
     m_Data  = buffer.Bytes;
     m_Size  = buffer.Length;
     m_Index = ReceiveQueue.PacketLengthSize + 2;    // 包头的长度和消息码长度
 }
Beispiel #19
0
        /// <summary>
        /// 收到网络消息包
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnSocketRecv(object sender, SocketRecvEventArgs <NetState> e)
        {
            var netState = e.Session.Data;

            netState.ReceiveBuffer.Enqueue(e.Buffer.Bytes, 0, e.Buffer.Length);

            var len = netState.ReceiveBuffer.GetPacketLength();

            do
            {
                if (len <= netState.ReceiveBuffer.Length)
                {
                    DogBuffer readBuffer;
                    if (len < 1024 * 4)
                    {
                        readBuffer = DogBuffer.GetFromPool4K();
                    }
                    else
                    {
                        readBuffer = DogBuffer.GetFromPool32K();
                    }

                    var get = netState.ReceiveBuffer.Dequeue(readBuffer.Bytes, 0, len);
                    if (get == len)
                    {
                        readBuffer.Length = len;

                        var packageReader = new PacketReader(readBuffer);
                        var packageId     = packageReader.GetPacketID();
                        var packetHandler = PacketHandlersManger.GetHandler(packageId);
                        if (packetHandler != null)
                        {
                            //  加入网络消息处理
                            if (_useManyTaskThread)
                            {
                                switch (packetHandler.TaskType)
                                {
                                case TaskType.Low:
                                    lowTask.AppendTask(netState, packetHandler, packageReader);
                                    break;

                                case TaskType.Assist:
                                    Logs.Debug("assist task.");
                                    assistTask.AppendTask(netState, packetHandler, packageReader);
                                    break;

                                default:
                                    mainTask.AppendTask(netState, packetHandler, packageReader);
                                    break;
                                }
                            }
                            else
                            {
                                mainTask.AppendTask(netState, packetHandler, packageReader);
                            }
                        }
                        else
                        {
                            Logs.Error("unknow packetid. code={0}", packageId);
                        }
                    }
                }
                //  一次网络消息可能会对应多个消息包,因此这里用循环获得消息包
                len = netState.ReceiveBuffer.GetPacketLength();
            } while (len > 0);
        }