Exemplo n.º 1
0
        void init_kcp(UInt32 conv)
        {
            m_Kcp = new KCPLib(conv, (byte[] buf, int size) => {
                m_UdpClient.Send(buf, size);
            });

            // fast mode.
            m_Kcp.NoDelay(1, 10, 2, 1);
            m_Kcp.WndSize(128, 128);
        }
Exemplo n.º 2
0
        void init_kcp(UInt32 conv)
        {
            m_Kcp = new KCPLib(conv, (byte[] buf, int size) => {
                m_KCPServer.Send(this, buf, 0, size);
            });

            // fast mode.
            m_Kcp.NoDelay(1, 10, 2, 1);
            m_Kcp.WndSize(128, 128);
        }
Exemplo n.º 3
0
        /// <summary>
        /// 发送数据。发送时,默认在头部加上4字节的key
        /// </summary>
        /// <param name="buf"></param>
        public void Send(byte[] buf)
        {
            byte[] newbuf = new byte[buf.Length + 4];
            //把key附上,服务端合法性检测用
            KCPLib.ikcp_encode32u(newbuf, 0, (uint)m_Key);
            Array.Copy(buf, 0, newbuf, 4, buf.Length);

            m_Kcp.Send(newbuf);
            m_NeedUpdateFlag = true;
            var e = Event;

            if (e != null)
            {
                e(UdpClientEvents.Send, buf);
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// 由Server.Update来调用,经过KCP处理后,如果确认是客户端发来的信息,则调用m_KCPServer.OnRecvData
        /// </summary>
        /// GG:修改代码采用回调,不直接调用 m_KCPServer
        internal void process_recv_queue(SocketAsyncEventArgs e)
        {
#if DEV
            IRQLog.AppLog.Log(this.m_netIndex.ToString() + ",接收1");
#endif
            m_Kcp.Input(e.Buffer, e.Offset, e.BytesTransferred);

            m_NeedUpdateFlag = true;

            for (var size = m_Kcp.PeekSize(); size > 0; size = m_Kcp.PeekSize())
            {
                byte[] buffer;
                buffer = (UdpLibConfig.UseBytePool ? m_KCPServer.BytePool.Rent(size) : new byte[size]);
                try
                {
                    if (m_Kcp.Recv(buffer) > 0)
                    {
                        m_LastRecvTimestamp = m_KCPServer.m_watch.Elapsed;

                        uint key = 0;
                        KCPLib.ikcp_decode32u(buffer, 0, ref key);
                        if (m_KCPServer.IsClientKeyCorrect(this.m_netIndex, (int)key) == false)
                        {
#if DEBUG
                            Console.WriteLine("index:{0} key 不对", this.m_netIndex);
#endif
                            m_KCPServer.BytePool.Return(buffer, true);
                            DisposeReason = ClientSessionDisposeReason.IndexKeyError;
                            //key不对
                            Dispose();
                            return;
                        }
#if DEV
                        IRQLog.AppLog.Log(this.m_netIndex.ToString() + ",接收2");
#endif
                        m_KCPServer.OnRecvData(this, buffer, 0, size);
                    }
                }
                finally
                {
                    if (UdpLibConfig.UseBytePool)
                    {
                        m_KCPServer.BytePool.Return(buffer, true);
                    }
                }
            }
        }
Exemplo n.º 5
0
        //发送握手数据 16字节 8字节头+4字节index+4字节key
        private void SendHandshake()
        {
            if (UdpLibConfig.DebugLevel != (int)UdpLibLogLevel.None)
            {
#if DEBUG
                Console.WriteLine("发送握手数据");
#endif
            }

            Interlocked.Increment(ref m_pktCounter);
            byte[] buf = new byte[UdpLibConfig.HandshakeDataSize + 4];
            Array.Copy(UdpLibConfig.HandshakeHeadData, buf, UdpLibConfig.HandshakeHeadData.Length);
            KCPLib.ikcp_encode32u(buf, UdpLibConfig.HandshakeHeadData.Length, m_NetIndex);
            KCPLib.ikcp_encode32u(buf, UdpLibConfig.HandshakeHeadData.Length + 4, (uint)m_Key);
            KCPLib.ikcp_encode32u(buf, UdpLibConfig.HandshakeHeadData.Length + 8, (uint)m_pktCounter);
            m_UdpClient.Send(buf, buf.Length);
#if DEV
            string s = string.Format("{0},发送握手数据,{1}", m_NetIndex, m_pktCounter.ToString());
            IRQLog.AppLog.Log(s);
            Console.WriteLine(s);
#endif
        }
Exemplo n.º 6
0
        /// <summary>
        /// 仅仅在UpdateRepeatedly里面调用。
        /// 如果是握手信息,则创建Session,并返回握手应答;否则让ClientSession自己处理。
        /// </summary>
        private void ProcessRecvQueue()
        {
            mRecvQueue.Switch();
            while (!mRecvQueue.Empty())
            {
                var e = mRecvQueue.Pop();
                if (e.BytesTransferred == 0)
                { //说明客户端关闭了,GG:UDP不知道客户端关闭的事情吧?
                    PushSAE(e);
                    continue;
                }

                uint index;
                if (TryProcessHandShake(e, out index))
                {
                    continue;
                }

                try
                {
                    KCPLib.ikcp_decode32u(e.Buffer, e.Offset, ref index);
                    var clientSession = GetSession(index);
                    if (clientSession != null && clientSession.Status == ClientSessionStatus.Connected)
                    {
                        Debug.Assert(clientSession.EndPoint.ToString() == e.RemoteEndPoint.ToString());
                        //c.EndPoint = e.RemoteEndPoint;

                        clientSession.process_recv_queue(e);
                    }
                }
                finally
                {  //GG: 使用Disposeale将PushSAE放在一起。简化代码。
                    PushSAE(e);
                }
            }
        }
Exemplo n.º 7
0
        private bool TryProcessHandShake(SocketAsyncEventArgs e, out uint index)
        {
            index = 0;
            uint key = 0;

            //使用纯udp进行握手,8字节0xFF+4字节conv+4字节key
            if (!IsHandshake(e.Buffer, e.Offset, e.BytesTransferred, out index, out key))
            {
                return(false);
            }

            var  c  = GetSession(index);
            uint cc = 0;

            KCPLib.ikcp_decode32u(e.Buffer, e.Offset + 16, ref cc);
            if (c == null)
            {
                //新连接处理,如果返回false,则不予处理,可以用来进行非法连接的初步处理
                if (NewSessionProcessor != null && !NewSessionProcessor.OnNewSession(index, e.RemoteEndPoint))
                {
                    PushSAE(e);
                    return(true);
                }

                c                     = AddSession(e.RemoteEndPoint, index);
                c.m_KCPServer         = this;
                c.m_LastRecvTimestamp = m_watch.Elapsed;
                NewClientSession?.Invoke(c, e.Buffer, e.Offset, e.BytesTransferred);
#if DEV
                IRQLog.AppLog.Log(index.ToString() + ",连接1," + cc.ToString());
#endif
            }
            else
            {
#if DEV
                IRQLog.AppLog.Log(index.ToString() + ",连接2," + cc.ToString());
#endif
                c.EndPoint = e.RemoteEndPoint;
                //如果客户端关闭并且立刻重连,这时候是连不上的,因为KCP中原有的数据不能正确处理
                //c.ResetKCP();
                //GG: 待处理。
            }

            c.Status = ClientSessionStatus.Connected;
            //回发握手请求
            if (UdpLibConfig.ServerSendAsync)
            {
                m_UdpSocket.SendToAsync(e);
            }
            else
            {
#if DEBUG
                Stopwatch sw = Stopwatch.StartNew();
                m_UdpSocket.SendTo(e.Buffer, e.Offset, e.BytesTransferred, SocketFlags.None, e.RemoteEndPoint);
                Console.WriteLine((sw.ElapsedTicks * 1000f / Stopwatch.Frequency));
#else
                m_UdpSocket.SendTo(e.Buffer, e.Offset, e.BytesTransferred, SocketFlags.None, e.RemoteEndPoint);
#endif
                PushSAE(e);
            }
#if DEV
            IRQLog.AppLog.Log(index.ToString() + ",发送数据UDP");
#endif
            return(true);
        }
Exemplo n.º 8
0
        private void ProcessRecvQueue()
        {
            mRecvQueue.Switch();
            while (!mRecvQueue.Empty())
            {
                var e = mRecvQueue.Pop();
                if (e.BytesTransferred == 0)
                {
                    PushSAE(e);
                    //说明客户端关闭了
                    continue;
                }
                uint index = 0, key = 0;
                //使用纯udp进行握手,8字节0xFF+4字节conv+4字节key
                if (IsHandshake(e.Buffer, e.Offset, e.BytesTransferred, out index, out key))
                {
                    var  c  = GetSession(index);
                    uint cc = 0;
                    KCPLib.ikcp_decode32u(e.Buffer, e.Offset + 16, ref cc);
                    if (c == null)
                    {
                        bool add = true;
                        //新连接处理,如果返回false,则不予处理,可以用来进行非法连接的初步处理
                        if (NewSessionProcessor != null)
                        {
                            add = NewSessionProcessor.OnNewSession(index, e.RemoteEndPoint);
                        }
                        if (add == false)
                        {
                            PushSAE(e);
                            continue;
                        }
                        c                     = AddSession(e.RemoteEndPoint, index);
                        c.m_KCPServer         = this;
                        c.m_LastRecvTimestamp = m_watch.Elapsed;
                        OnNewClientSession(c, e.Buffer, e.Offset, e.BytesTransferred);
#if DEV
                        IRQLog.AppLog.Log(index.ToString() + ",连接1," + cc.ToString());
#endif
                    }
                    else
                    {
#if DEV
                        IRQLog.AppLog.Log(index.ToString() + ",连接2," + cc.ToString());
#endif
                        c.EndPoint = e.RemoteEndPoint;
                        //如果客户端关闭并且立刻重连,这时候是连不上的,因为KCP中原有的数据不能正确处理
                        //c.ResetKCP();
                    }

                    c.Status = ClientSessionStatus.Connected;
                    //回发握手请求
                    if (UdpLibConfig.ServerSendAsync)
                    {
                        m_UdpSocket.SendToAsync(e);
                    }
                    else
                    {
#if DEBUG
                        Stopwatch sw = Stopwatch.StartNew();
                        m_UdpSocket.SendTo(e.Buffer, e.Offset, e.BytesTransferred, SocketFlags.None, e.RemoteEndPoint);
                        Console.WriteLine((sw.ElapsedTicks * 1000f / Stopwatch.Frequency));
#else
                        m_UdpSocket.SendTo(e.Buffer, e.Offset, e.BytesTransferred, SocketFlags.None, e.RemoteEndPoint);
#endif
                        PushSAE(e);
                    }
#if DEV
                    IRQLog.AppLog.Log(index.ToString() + ",发送数据UDP");
#endif
                }
                else
                {
                    try {
                        KCPLib.ikcp_decode32u(e.Buffer, e.Offset, ref index);
                        var c = GetSession(index);
                        if (c != null && c.Status == ClientSessionStatus.Connected)
                        {
                            Debug.Assert(c.EndPoint.ToString() == e.RemoteEndPoint.ToString());
                            //c.EndPoint = e.RemoteEndPoint;

                            c.process_recv_queue(e);
                        }
                    }
                    finally {
                        PushSAE(e);
                    }
                }
            }
        }