Exemplo n.º 1
0
        public void HandleRecv(byte[] date, int offset, int length)
        {
            if (this.IsDisposed)
            {
                return;
            }

            this.isConnected = true;

            Kcp.KcpInput(this.kcp, date, offset, length);
            this.GetService().AddToUpdateNextTime(0, this.Id);

            while (true)
            {
                if (this.IsDisposed)
                {
                    return;
                }
                int n = Kcp.KcpPeeksize(this.kcp);
                if (n < 0)
                {
                    return;
                }
                if (n == 0)
                {
                    this.OnError((int)SocketError.NetworkReset);
                    return;
                }

                byte[] buffer = this.memoryStream.GetBuffer();
                this.memoryStream.SetLength(n);
                this.memoryStream.Seek(0, SeekOrigin.Begin);
                int count = Kcp.KcpRecv(this.kcp, buffer, ushort.MaxValue);
                if (n != count)
                {
                    return;
                }
                if (count <= 0)
                {
                    return;
                }

                this.lastRecvTime = this.GetService().TimeNow;

                this.OnRead(this.memoryStream);
            }
        }
Exemplo n.º 2
0
        public void WaitSnd()
        {
            void Output(byte[] data, int len)
            {
            }

            // setup KCP
            Kcp kcp = new Kcp(0, Output);

            // add some to send buffer and send queue
            kcp.snd_buf.Add(new Segment());
            kcp.snd_buf.Add(new Segment());
            kcp.snd_queue.Enqueue(new Segment());

            // WaitSnd should be send buffer + queue
            Assert.That(kcp.WaitSnd, Is.EqualTo(3));
        }
Exemplo n.º 3
0
 public void LostLink(Kcp kcp)
 {
     if (_networkLinks == null)
     {
         return;
     }
     if (_cmdBuffer == null)
     {
         _cmdBuffer = new byte[1] {
             NetworkCmd.FIN
         };
     }
     _Socket.SendTo(_cmdBuffer, 1, SocketFlags.None, _remote);
     if (_networkLinks.TryRemove(_remote, out var link))
     {
         link.Stop();
     }
 }
Exemplo n.º 4
0
        // accept
        public KChannel(uint localConn, uint remoteConn, Socket socket, IPEndPoint remoteEndPoint, KService kService) : base(kService, ChannelType.Accept)
        {
            this.memoryStream = this.GetService().MemoryStreamManager.GetStream("message", ushort.MaxValue);

            this.LocalConn      = localConn;
            this.RemoteConn     = remoteConn;
            this.remoteEndPoint = remoteEndPoint;
            this.socket         = socket;
            this.kcp            = Kcp.KcpCreate(this.RemoteConn, new IntPtr(this.LocalConn));

            SetOutput();
            Kcp.KcpNodelay(this.kcp, 1, 10, 1, 1);
            Kcp.KcpWndsize(this.kcp, 256, 256);
            Kcp.KcpSetmtu(this.kcp, 470);
            this.lastRecvTime = kService.TimeNow;
            this.createTime   = kService.TimeNow;
            this.Accept();
        }
Exemplo n.º 5
0
        public override void Dispose()
        {
            if (this.IsDisposed)
            {
                return;
            }

            base.Dispose();


            if (this.m_Kcp != IntPtr.Zero)
            {
                Kcp.KcpRelease(this.m_Kcp);
                this.m_Kcp = IntPtr.Zero;
            }
            this.m_Socket = null;
            this.m_MemoryStream.Dispose();
        }
Exemplo n.º 6
0
        public void Dispose()
        {
            lock (this)
            {
                if (m_Dispose)
                {
                    return;
                }
                m_Dispose = true;
            }

            m_IsConnected = false;
            m_Kcp.Dispose();

            m_Kcp          = null;
            m_Socket       = null;
            m_Point        = null;
            m_OutputBuffer = null;
        }
Exemplo n.º 7
0
        public void Check()
        {
            void Output(byte[] data, int len)
            {
            }

            // setup KCP
            Kcp kcp = new Kcp(0, Output);

            // update at time = 1
            kcp.Update(1);

            // check at time = 2
            uint next = kcp.Check(2);

            // check returns 'ts_flush + interval', or in other words,
            // 'interval' seconds after UPDATE was called. so 1+100 = 101.
            Assert.That(next, Is.EqualTo(1 + kcp.interval));
        }
Exemplo n.º 8
0
        internal KcpHelper(uint conv, int mtu, int winSize, KcpMode kcpMode, IKcp listener)
        {
            kcp = new Kcp(conv, this);
            if (kcpMode == KcpMode.Normal)
            {
                kcp.NoDelay(0, 40, 0, 0);
            }
            else if (kcpMode == KcpMode.Fast)
            {
                kcp.NoDelay(1, 10, 2, 1);
            }
            kcp.WndSize(winSize, winSize);
            kcp.SetMtu(mtu);

            kcpListener = listener;

            timeFlow = BaseTimeFlow.CreateTimeFlow(this);
            timeFlow.StartTimeFlowES();
        }
Exemplo n.º 9
0
        /**
         * Creates a new instance.
         *
         * @param output output for kcp
         */
        public Ukcp(KcpOutput output, KcpListener kcpListener, IMessageExecutor iMessageExecutor,
                    ReedSolomon reedSolomon, ChannelConfig channelConfig)
        {
            this._channelConfig    = channelConfig;
            this.kcp               = new Kcp(channelConfig.Conv, output);
            this.active            = true;
            this._kcpListener      = kcpListener;
            this._iMessageExecutor = iMessageExecutor;
            //默认2<<11   可以修改
            _writeQueue = new MpscArrayQueue <IByteBuffer>(2 << 10);
            _readQueue  = new MpscArrayQueue <IByteBuffer>(2 << 10);
            //recieveList = new SpscLinkedQueue<>();
            int headerSize = 0;

            if (channelConfig.KcpTag)
            {
                headerSize += KCP_TAG;
            }

            //init crc32
            if (channelConfig.Crc32Check)
            {
                var kcpOutput = kcp.Output;
                kcpOutput   = new Crc32OutPut(kcpOutput, headerSize);
                kcp.Output  = kcpOutput;
                headerSize += HEADER_CRC;
            }

            //init fec
            if (reedSolomon != null)
            {
                var kcpOutput = kcp.Output;
                _fecEncode  = new FecEncode(headerSize, reedSolomon, channelConfig.Mtu);
                _fecDecode  = new FecDecode(3 * reedSolomon.getTotalShardCount(), reedSolomon, channelConfig.Mtu);
                kcpOutput   = new FecOutPut(kcpOutput, _fecEncode);
                kcp.Output  = kcpOutput;
                headerSize += Fec.fecHeaderSizePlus2;
            }

            kcp.setReserved(headerSize);
            intKcpConfig(channelConfig);
        }
Exemplo n.º 10
0
        public void HandleConnnect(uint remoteConn)
        {
            if (this.isConnected)
            {
                return;
            }

            this.RemoteConn = remoteConn;

            this.kcp = Kcp.KcpCreate(this.RemoteConn, new IntPtr(this.LocalConn));
            SetOutput();
            Kcp.KcpNodelay(this.kcp, 1, 10, 1, 1);
            Kcp.KcpWndsize(this.kcp, 256, 256);
            Kcp.KcpSetmtu(this.kcp, 470);

            this.isConnected  = true;
            this.lastRecvTime = this.GetService().TimeNow;

            HandleSend();
        }
Exemplo n.º 11
0
    public override void Dispose()
    {
        m_isRunning  = false;
        senderBuffer = null;
        recvThread.Abort();

        if (udpClient != null)
        {
            udpClient.Dispose();
            udpClient = null;
        }

        if (kcpClient == null)
        {
            return;
        }
        kcpClient.Dispose();
        kcpClient = null;

        State = EConnetState.EClosed;
    }
Exemplo n.º 12
0
        public void ShrinkBufFilledSendBuffer()
        {
            void Output(byte[] data, int len)
            {
            }

            // setup KCP
            Kcp kcp = new Kcp(0, Output);

            // add some to send buffer and send queue
            kcp.snd_buf.Add(new Segment {
                sn = 2
            });
            kcp.snd_buf.Add(new Segment {
                sn = 3
            });

            // ShrinkBuf should set snd_una to first send buffer element's 'sn'
            kcp.ShrinkBuf();
            Assert.That(kcp.snd_una, Is.EqualTo(2));
        }
Exemplo n.º 13
0
        /// <summary>
        /// 收到ACK,连接建立
        /// </summary>
        /// <param name="channelId"></param>
        public void HandleConnnect(uint channelId)
        {
            if (this.isConnected)
            {
                return;
            }
            this.isConnected = true;

            //id替换为服务端分配的
            this.Id  = channelId;
            this.kcp = new Kcp(channelId, this.OnKcpSend);
            kcp.SetMtu(512);
            kcp.NoDelay(1, 10, 2, 1);  //fast

            //有缓存的数据包发出去
            while (this.sendBuffer.Count > 0)
            {
                byte[] buffer = this.sendBuffer.Dequeue();
                this.KcpSend(buffer);
            }
        }
Exemplo n.º 14
0
        public void HandleConnnect(uint remoteConn)
        {
            if (this.IsConnected)
            {
                return;
            }

            this.RemoteConn = remoteConn;

            this.m_Kcp = Kcp.KcpCreate(this.RemoteConn, new IntPtr(this.LocalConn));
            SetOutput();
            Kcp.KcpNodelay(this.m_Kcp, 1, 10, 1, 1);
            Kcp.KcpWndsize(this.m_Kcp, 256, 256);
            Kcp.KcpSetmtu(this.m_Kcp, 470);

            m_ChannelState      = ChannelState.EConnected;
            this.m_LastRecvTime = this.GetService().TimeNow;
            GetService().RemoveWaitConnectChannels(RemoteConn);

            HandleSend();
        }
Exemplo n.º 15
0
        /// <summary>
        /// 创建channel,分为客户端请求和服务端接受两种情况
        /// </summary>
        /// <param name="service"></param>
        /// <param name="id"></param>
        /// <param name="remoteEndPoint"></param>
        /// <param name="socket"></param>
        public KChannel(ChannelType ctype, KService service, uint id, IPEndPoint remoteEndPoint, UdpClient socket) : base(service)
        {
            this.Id = id;
            //this.RemoteId = remoteid;
            this.remoteEndPoint = remoteEndPoint;
            this.socket         = socket;
            this.parser         = new PacketParser(this.recvBuffer);
            this.lastRecvTime   = service.TimeNow;
            this.channelType    = ctype;
            if (ctype == ChannelType.Connect)
            {
                this.Connect(service.TimeNow);
            }
            else if (ctype == ChannelType.Accept)
            {
                kcp = new Kcp(this.Id, this.OnKcpSend);
                kcp.SetMtu(512);
                kcp.NoDelay(1, 10, 2, 1);  //fast

                this.isConnected = true;
            }
        }
Exemplo n.º 16
0
        protected override void OnReceived(EndPoint endpoint, byte[] buffer, long offset, long size)
        {
            // Continue receive datagrams.
            if (size == 0)
            {
                // Important: Receive using thread pool is necessary here to avoid stack overflow with Socket.ReceiveFromAsync() method!
                ThreadPool.QueueUserWorkItem(o => { ReceiveAsync(); });
            }
            if (size > 0)
            {
                if (!Session.TryGetValue(endpoint, out Kcp kcp))
                {
                    kcp = Kcp.Create(userData: endpoint);
                    kcp.SetOutput(KcpSend);
                    Session.Add(endpoint, kcp);
                }
                kcp.Input(buffer);

                // Echo the message back to the sender
                kcp.Send(buffer.AsSpan().Slice((int)offset, (int)size));
            }
        }
Exemplo n.º 17
0
        /// <summary>
        /// 初始化Kcp
        /// </summary>
        public void InitKcp()
        {
            //当这个Peer曾被使用过时,先释放它的Kcp,在重设
            if (Kcp != null)
            {
                Kcp.Dispose();
            }

            //初始化Kcp
            handle = new Handle(LocalSocket, Remote);
            Kcp    = new Kcp(Conv, handle);
            if (model == Model.FAST)
            {
                Kcp.NoDelay(1, 10, 2, 1);//fast
            }
            else
            {
                Kcp.NoDelay(0, 40, 0, 0);//normal
            }
            Kcp.WndSize(64, 64);
            Kcp.SetMtu(512);
        }
Exemplo n.º 18
0
        // Accept
        public KChannel(uint localConn, uint remoteConn, Socket m_Socket, IPEndPoint m_RemoteEndPoint, KService kService) : base(kService, ChannelType.Accept)
        {
            this.m_MemoryStream = this.GetService().MemoryStreamManager.GetStream(NetWorkConstant.Str_Msg, ushort.MaxValue);

            this.LocalConn        = localConn;
            this.RemoteConn       = remoteConn;
            this.m_RemoteEndPoint = m_RemoteEndPoint;
            this.m_Socket         = m_Socket;
            this.m_Kcp            = Kcp.KcpCreate(this.RemoteConn, new IntPtr(this.LocalConn));


            ///Kcp 参数
            SetOutput();
            Kcp.KcpNodelay(this.m_Kcp, 1, 10, 1, 1);
            Kcp.KcpWndsize(this.m_Kcp, 256, 256);
            Kcp.KcpSetmtu(this.m_Kcp, 470);
            ///



            this.Accept();
        }
Exemplo n.º 19
0
        /// <summary>
        /// sends a packet to a kcp, simulating unreliable network
        /// </summary>
        /// <param name="target"></param>
        /// <param name="data"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public virtual async UniTaskVoid SendAsync(Kcp target, byte[] data, int length, CancellationToken token)
        {
            // drop some packets
            if (Random.value < pdrop)
            {
                return;
            }

            int latency = Random.Range(0, maxLat);

            if (latency > 0)
            {
                await UniTask.Delay(latency, false, PlayerLoopTiming.Update, token);
            }

            target.Input(data, length);

            // duplicate some packets (udp can duplicate packets)
            if (Random.value < pdup)
            {
                target.Input(data, length);
            }
        }
Exemplo n.º 20
0
        public void ParseAckSndNxtSmaller()
        {
            void Output(byte[] data, int len)
            {
            }

            // setup KCP
            Kcp kcp = new Kcp(0, Output);

            // insert three segments into send buffer
            Segment one = new Segment {
                sn = 1
            };

            kcp.snd_buf.Add(one);
            Segment two = new Segment {
                sn = 2
            };

            kcp.snd_buf.Add(two);
            Segment three = new Segment {
                sn = 3
            };

            kcp.snd_buf.Add(three);

            // parse ack only removes if sn < snd_nxt.
            // it should do nothing if snd_nxt is <= sn
            kcp.snd_nxt = 1;

            // parse ack with sn == 3, should remove the last segment
            kcp.ParseAck(1);
            Assert.That(kcp.snd_buf.Count, Is.EqualTo(3));
            Assert.That(kcp.snd_buf[0], Is.EqualTo(one));
            Assert.That(kcp.snd_buf[1], Is.EqualTo(two));
            Assert.That(kcp.snd_buf[2], Is.EqualTo(three));
        }
Exemplo n.º 21
0
 public KCPHandle(Socket dataSocket, uint iconv)
 {
     kcp             = new Kcp(iconv, this);
     this.dataSocket = dataSocket;
 }
Exemplo n.º 22
0
 public KcpTestClient(string address, int port, int messages) : base(address, port)
 {
     _messages = messages;
     kcp       = Kcp.Create();
     kcp.SetOutput(KcpOutput);
 }
Exemplo n.º 23
0
        void KPRPCReceiveSetup(KPRPCMessage kprpcm)
        {
            if (this.Authorised)
            {
                KPRPCMessage data2client = new KPRPCMessage();
                data2client.protocol = "setup";
                data2client.srp      = new SRPParams();
                data2client.version  = ProtocolVersion;

                data2client.error = new Error(ErrorCode.AUTH_RESTART, new string[] { "Already authorised" });
                this.Authorised   = false;

                string response = Jayrock.Json.Conversion.JsonConvert.ExportToString(data2client);
                this.WebSocketConnection.Send(response);

                return;
            }



            if (kprpcm.srp != null)
            {
                KPRPCMessage data2client = new KPRPCMessage();
                data2client.protocol = "setup";
                data2client.version  = ProtocolVersion;

                int clientSecurityLevel = kprpcm.srp.securityLevel;

                if (clientSecurityLevel < securityLevelClientMinimum)
                {
                    data2client.error = new Error(ErrorCode.AUTH_CLIENT_SECURITY_LEVEL_TOO_LOW, new string[] { securityLevelClientMinimum.ToString() });

                    /* TODO1.3: need to disconnect/delete/reset this connection once we've decided we are not interested in letting the client connect. Maybe
                     * tie in to finding a way to abort if user clicks a "cancel" button on the auth form.
                     */
                    this.WebSocketConnection.Send(Jayrock.Json.Conversion.JsonConvert.ExportToString(data2client));
                }
                else
                {
                    switch (kprpcm.srp.stage)
                    {
                    case "identifyToServer": this.WebSocketConnection.Send(SRPIdentifyToServer(kprpcm)); break;

                    case "proofToServer": this.WebSocketConnection.Send(SRPProofToServer(kprpcm)); break;

                    default: return;
                    }
                }
            }
            else
            {
                KPRPCMessage data2client = new KPRPCMessage();
                data2client.protocol = "setup";
                data2client.version  = ProtocolVersion;

                int clientSecurityLevel = kprpcm.key.securityLevel;

                if (clientSecurityLevel < securityLevelClientMinimum)
                {
                    data2client.error = new Error(ErrorCode.AUTH_CLIENT_SECURITY_LEVEL_TOO_LOW, new string[] { securityLevelClientMinimum.ToString() });

                    /* TODO1.3: need to disconnect/delete/reset this connection once we've decided we are not interested in letting the client connect. Maybe
                     * tie in to finding a way to abort if user clicks a "cancel" button on the auth form.
                     */
                    this.WebSocketConnection.Send(Jayrock.Json.Conversion.JsonConvert.ExportToString(data2client));
                }
                else
                {
                    if (!string.IsNullOrEmpty(kprpcm.key.username))
                    {
                        // confirm username
                        this.userName = kprpcm.key.username;
                        KeyContainerClass kc = this.KeyContainer;

                        if (kc == null)
                        {
                            this.userName     = null;
                            data2client.error = new Error(ErrorCode.AUTH_FAILED, new string[] { "Stored key not found - Caused by changed Firefox profile or KeePass instance; changed OS user credentials; or KeePass config file may be corrupt" });

                            /* TODO1.3: need to disconnect/delete/reset this connection once we've decided we are not interested in letting the client connect. Maybe
                             * tie in to finding a way to abort if user clicks a "cancel" button on the auth form.
                             */
                            this.WebSocketConnection.Send(Jayrock.Json.Conversion.JsonConvert.ExportToString(data2client));
                            return;
                        }
                        if (kc.Username != this.userName)
                        {
                            this.userName     = null;
                            data2client.error = new Error(ErrorCode.AUTH_FAILED, new string[] { "Username mismatch - KeePass config file is probably corrupt" });

                            /* TODO1.3: need to disconnect/delete/reset this connection once we've decided we are not interested in letting the client connect. Maybe
                             * tie in to finding a way to abort if user clicks a "cancel" button on the auth form.
                             */
                            this.WebSocketConnection.Send(Jayrock.Json.Conversion.JsonConvert.ExportToString(data2client));
                            return;
                        }
                        if (kc.AuthExpires < DateTime.UtcNow)
                        {
                            this.userName     = null;
                            data2client.error = new Error(ErrorCode.AUTH_EXPIRED);

                            /* TODO1.3: need to disconnect/delete/reset this connection once we've decided we are not interested in letting the client connect. Maybe
                             * tie in to finding a way to abort if user clicks a "cancel" button on the auth form.
                             */
                            this.WebSocketConnection.Send(Jayrock.Json.Conversion.JsonConvert.ExportToString(data2client));
                            return;
                        }

                        this.WebSocketConnection.Send(Kcp.KeyChallengeResponse1(this.userName, securityLevel));
                    }
                    else if (!string.IsNullOrEmpty(kprpcm.key.cc) && !string.IsNullOrEmpty(kprpcm.key.cr))
                    {
                        bool authorised = false;
                        this.WebSocketConnection.Send(Kcp.KeyChallengeResponse2(kprpcm.key.cc, kprpcm.key.cr, KeyContainer, securityLevel, out authorised));
                        Authorised = authorised;
                        if (authorised)
                        {
                            // We assume the user has manually verified the client name as part of the initial SRP setup so it's fairly safe to use it to determine the type of client connection to which we want to promote our null connection
                            KPRPC.PromoteNullRPCClient(this, KeyContainer.ClientName);
                        }
                    }
                }
            }
        }
Exemplo n.º 24
0
 public static KcpOp Send(Kcp kcp, Memory <byte> buff) => new KcpOp(kcp, kop.send, buff);
Exemplo n.º 25
0
 public static KcpOp OnReceive(Kcp kcp, Memory <byte> buff) => new KcpOp(kcp, kop.send, buff);
Exemplo n.º 26
0
 private KcpOp(Kcp kcp, kop op, Memory <byte> buff)
 {
     this.op   = op;
     this.kcp  = kcp;
     this.buff = buff;
 }
Exemplo n.º 27
0
        public void Run(uint conv, IKcpCallback kcpCallback)
        {
            _recvFromRemote = new BufferBlock <DataPackage>();
            _recvFromLocal  = new BufferBlock <DataPackage>();

            Conv = conv;

            _kcp = new Kcp(conv, kcpCallback, KcpRentable.Instacne);
            _kcp.NoDelay(1, 10, 2, 1); // 极速模式
            _kcp.WndSize(128, 128);
            _kcp.SetMtu(MTU);

            _tokenSource = new CancellationTokenSource();

            //  这样写的目的,在服务器上,压解缩、加解密可以利用多核(多个KCP连接之间的压解缩、加解密是可以并行的)
            //  update
            Task.Factory.StartNew(async() => {
                //  检测并Flush数据到远端
                while (!_tokenSource.IsCancellationRequested)
                {
                    try {
                        _kcp.Update(DateTime.UtcNow);
                        await _kcp.CheckAwait(DateTime.UtcNow, _tokenSource.Token);
                    }
                    catch (TaskCanceledException) {
                        break;
                    }
                    catch (ObjectDisposedException e) {
                        //  一般情况下,OutPut时使用Socket发送数据时,而Socket被关闭时会进入此分支;暂时这么处理
                        if (e.ObjectName == "System.Net.Sockets.Socket")
                        {
                            break;
                        }
                        Debug.LogErrorFormat("Kcp.updateTask: \r\n {0}", e);
                    }
                }
            }, _tokenSource.Token);

            //  input from lower level
            Task.Factory.StartNew(async() => {
                //  收到 Ack 帧,需要移除 snd_buf;收到数据帧,则需要 Flush Ack
                while (!_tokenSource.IsCancellationRequested)
                {
                    DataPackage package = null;
                    try {
                        package    = await _recvFromRemote.ReceiveAsync(_tokenSource.Token);
                        var result = _kcp.Input(package.MemoryOwner.Memory.Span.Slice(package.Offset, package.Lenght));
                        while (result == 0)
                        {
                            var(memoryOwner, avalidLength) = _kcp.TryRecv();
                            if (memoryOwner == null)
                            {
                                break;
                            }
                            //  在此解压、解密
                            OnRecvKcpPackage?.Invoke(memoryOwner, avalidLength, this);
                        }
                        ;
                    }
                    catch (TaskCanceledException) {
                        _recvFromRemote.Complete();
                        break;
                    }
                    catch (Exception e) {
                        Debug.LogErrorFormat("Kcp.inputTask: \r\n {0}", e);
                    }
                    finally {
                        if (package != null)
                        {
                            package.MemoryOwner.Dispose();
                            DataPackage.Pool.Return(package);
                        }
                    }
                }
            }, _tokenSource.Token);

            //  send by user
            Task.Factory.StartNew(async() => {
                //  有可能需要发送帧,需要Flush Snd_Queue
                while (!_tokenSource.IsCancellationRequested)
                {
                    DataPackage package = null;
                    try {
                        package = await _recvFromLocal.ReceiveAsync(_tokenSource.Token);
                        //  在此压缩、加密
                        _kcp.Send(package.MemoryOwner.Memory.Span.Slice(0, package.Lenght));
                    }
                    catch (TaskCanceledException) {
                        _recvFromLocal.Complete();
                        break;
                    }
                    catch (Exception e) {
                        Debug.LogErrorFormat("Kcp.sendTask: \r\n {0}", e);
                    }
                    finally {
                        if (package != null)
                        {
                            package.MemoryOwner.Dispose();
                            DataPackage.Pool.Return(package);
                        }
                    }
                }
            }, _tokenSource.Token);
        }
Exemplo n.º 28
0
        public KcpClient(UdpServer udpserver, EndPoint remoteendpoint) : base(udpserver, remoteendpoint)
        {
#if LOOPBACKTEST
            onUserLevelReceivedCompleted += (ref byte[] buffer) => {
                byte[] idbuffer = new byte[KcpChannel.idlength];
                Array.ConstrainedCopy(buffer, 0, idbuffer, 0, 32);
#if UTF16
                var idstr = System.Text.Encoding.Unicode.GetString(idbuffer);
#else
                var idstr = System.Text.Encoding.UTF8.GetString(idbuffer);
#endif
                bool bcontain = KcpChannelManager.OnchannelReceivedatacallbackmap.ContainsKey(idstr);
                if (bcontain)
                {
                    if (KcpChannelManager.OnchannelReceivedatacallbackmap[idstr].mkcpclient.mremoteEP == mremoteEP)
                    {
                    }
                    else
                    {
                        // KcpChannelManager.OnchannelReceivedatacallbackmap[idstr].mkcpclient.mremoteEP = mremoteEP;

                        KcpChannelManager.OnchannelReceivedatacallbackmap.Remove(idstr);
                        KcpChannelManager.OnchannelReceivedatacallbackmap.Add(idstr, new KcpChannel(idstr, this));//need verify
                    }
                }
                else
                {
                    KcpChannelManager.OnchannelReceivedatacallbackmap.Add(idstr, new KcpChannel(idstr, this));
                }
                int    datasize   = buffer.Length - KcpChannel.idlength;
                byte[] databuffer = new byte[datasize];
                Array.ConstrainedCopy(buffer, KcpChannel.idlength, databuffer, 0, datasize);
                KcpChannelManager.OnchannelReceivedatacallbackmap[idstr].Onreceivedata(ref databuffer);

                #region
                //byte[] latitudebuffer = new byte[4];
                //Array.ConstrainedCopy(buffer, 32, latitudebuffer, 0, 4);
                //float latitude = ByteArraytoChannelidType.DeSerialize(ref latitudebuffer);

                //byte[] longitudebuffer = new byte[4];
                //Array.ConstrainedCopy(buffer, 32+4, longitudebuffer, 0, 4);
                //float longitude = ByteArraytoChannelidType.DeSerialize(ref longitudebuffer);

                //Console.ForegroundColor = ConsoleColor.Blue;
                //Console.WriteLine(idstr);
                //Console.WriteLine(latitude.ToString());
                //Console.WriteLine(longitude.ToString());
                //Console.ForegroundColor = ConsoleColor.White;
                //userlevelsend(ref buffer);
                #endregion
            };
#endif
            kcphandle handle = new kcphandle();
            OnReceivedCompletePointer = (ref byte[] buffer) => {
                mKcp.Input(buffer);//buffer is received from low level data
            };
            handle.Out = buffer => {
                mudpserver.UdpListener.SendTo(buffer.ToArray(), mremoteEP);//low level send
            };
            mKcp = new Kcp((uint)(5598781), handle);
            mKcp.NoDelay(1, 5, 2, 1);//fast
            mKcp.WndSize(64, 64);
            mKcp.SetMtu(512);
            Task.Run(async() =>
            {
                try
                {
                    int updateCount = 0;
                    while (true)
                    {
                        mKcp.Update(DateTime.UtcNow);

                        int len;
                        while ((len = mKcp.PeekSize()) > 0)
                        {
                            var buffer = new byte[len];
                            if (mKcp.Recv(buffer) >= 0)
                            {
                                onUserLevelReceivedCompleted.Invoke(ref buffer);
                            }
                        }
                        await Task.Delay(1);
                        updateCount++;
                        if (updateCount % 1000 == 0)
                        {
                            Console.WriteLine($"KCP ALIVE {updateCount}----");
                        }
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                }
            });
        }
        public KcpClient(string ip, int port)
        {
            IPAddress ipAd = IPAddress.Parse(ip);        //local ip address  "172.16.5.188"

            remoteEndPoint = new IPEndPoint(ipAd, port); //27001
            m_Socket       = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
#if LOOPBACKTEST
            onUserLevelReceivedCompleted += (ref byte[] buffer) => {
#if UTF16
                var str = System.Text.Encoding.Unicode.GetString(buffer);
#else
                var str = System.Text.Encoding.UTF8.GetString(buffer);
#endif
                Console.WriteLine(str);
                //userlevelsend(ref buffer);
            };
#endif
            kcphandle handle = new kcphandle();
            handle.Out = buffer => {
                m_Socket.SendTo(buffer.ToArray(), remoteEndPoint);//low level send
            };
            mKcp = new Kcp((uint)(5598781), handle);
            mKcp.NoDelay(1, 5, 2, 1);//fast
            mKcp.WndSize(64, 64);
            mKcp.SetMtu(512);
            Task.Run(async() =>
            {
                try
                {
                    int updateCount = 0;
                    while (true)
                    {
                        mKcp.Update(DateTime.UtcNow);

                        int len;
                        while ((len = mKcp.PeekSize()) > 0)
                        {
                            var buffer = new byte[len];
                            if (mKcp.Recv(buffer) >= 0)
                            {
                                onUserLevelReceivedCompleted.Invoke(ref buffer);
                            }
                        }
                        await Task.Delay(5);
                        updateCount++;
                        if (updateCount % 1000 == 0)
                        {
                            Console.WriteLine($"KCP ALIVE {updateCount}----");
                        }
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                }
            });
            Task.Run(
                async() =>
            {
                EndPoint remoteEP     = new IPEndPoint(1, 1);
                byte[] receivedbuffer = new Byte[65507];
                await Task.Delay(1);
                while (true)
                {
                    try
                    {
                        int bytesReceived  = m_Socket.ReceiveFrom(receivedbuffer, ref remoteEP);   //here is a block call ,wait until it receive data
                        byte[] validbuffer = new byte[bytesReceived];
                        Array.ConstrainedCopy(receivedbuffer, 0, validbuffer, 0, bytesReceived);
                        mKcp.Input(validbuffer);    //buffer is received from low level data
                        //await Task.Delay(1);
                    }
                    catch
                    {
                    }
                }
            }
                );
        }
Exemplo n.º 30
0
        public static void Connect()
        {
            socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            socket.Bind(new IPEndPoint(IPAddress.Any, 8880));

            Console.WriteLine("UDP服务端启动");

            mHandler = new KcpHandler();
            mKcp     = new Kcp(10, mHandler);
            mKcp.NoDelay(1, 10, 2, 1);
            mKcp.WndSize(64, 64);
            mKcp.SetMtu(512);

            proto = new ReceiveProto();

            mHandler.Out += buffer =>
            {
                Console.WriteLine("mHandler Out IP{0} port{1}", (ep as IPEndPoint).Address, (ep as IPEndPoint).Port);
                socket.SendTo(buffer.ToArray(), ep);
            };

            mHandler.Recv += buffer =>
            {
                proto.Receive(buffer);
            };

            Task.Run(async() =>
            {
                try
                {
                    while (true)
                    {
                        mKcp.Update(DateTime.UtcNow);
                        int len;
                        //方法1
                        while ((len = mKcp.PeekSize()) > 0)
                        {
                            byte[] buffer = new byte[len];
                            if (mKcp.Recv(buffer) >= 0)
                            {
                                Console.WriteLine("mHandler Receive");
                                mHandler.Receive(buffer);
                            }
                        }
                        //方法2
                        // do
                        // {
                        //     var (buffer, avalidSize) = mKcp.TryRecv();
                        //     len = avalidSize;
                        //     if (buffer != null)
                        //     {
                        //         var temp = new byte[len];
                        //         buffer.Memory.Span.Slice(0, len).CopyTo(temp);
                        //         Console.WriteLine("mKcp Receive");
                        //         mHandler.Receive(temp);
                        //     }
                        // } while (len > 0);

                        await Task.Delay(5);
                    }
                }
                catch (Exception e)
                {
                    e.ToString();
                }
            });

            ep   = new IPEndPoint(IPAddress.Any, 0);
            data = new byte[1024];

            Thread threadReceive = new Thread(Receive);

            threadReceive.IsBackground = true;
            threadReceive.Start();
        }