Beispiel #1
0
 internal void Input(byte[] buffer, int offset, int length)
 {
     if (m_Dispose)
     {
         return;
     }
     m_Kcp.Input(new Span <byte>(buffer, offset, length));
 }
        public KcpClient(UdpServer udpserver, EndPoint remoteendpoint) : base(udpserver, remoteendpoint)
        {
#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.ForegroundColor = ConsoleColor.Blue;
                Console.WriteLine(str);
                Console.ForegroundColor = ConsoleColor.White;
                userlevelsend(ref buffer);
            };
#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);
                }
            });
        }
Beispiel #3
0
        public void MockInput(Span <byte> span)
        {
            var next = random.Next(100);

            if (next >= 0)///随机丢包
            {
                _kcp.Input(span);
            }
        }
Beispiel #4
0
 /// <summary>
 /// 上层kcp接收
 /// </summary>
 /// <param name="data"></param>
 internal void Recv(byte[] data)
 {
     if (data != null)
     {
         kcp.Input(data);
         CheckRecv();
         lock (m_lock) nextUpdateTime = DateTime.UtcNow;
         Interlocked.Exchange(ref noNetDataCount, 0);
     }
 }
Beispiel #5
0
        private async void Timer()
        {
            int interval = 500;
            var sw       = new Stopwatch();
            var swait    = new SpinWait();

            while (true)
            {
                if (!kcpOps.TryDequeue(out KcpOp op))
                {
                    swait.SpinOnce();
                }
                else
                {
                    switch (op.op)
                    {
                    case kop.connect: //连接
                    case kop.send:    //发送
                        kcp.Send(op.buff.Span);
                        break;

                    case kop.onUdpRecive:    //Udp接收
                        kcp.Input(op.buff.Span);
                        break;

                    case kop.onRecive:    //kcp接收
                        break;

                    case kop.close:    //关闭
                        break;
                    }
                }
                if (sw.ElapsedMilliseconds > interval)   //timeout
                {
                    sw.Restart();
                    OnTick();
                }
            }
        }
Beispiel #6
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);
            }
        }
Beispiel #7
0
        public void RecvData(IByteBuffer buf, out IByteBuffer outBuffer)
        {
            buf = buf.WithOrder(ByteOrder.LittleEndian);

            mKcp.Input(buf);

            outBuffer = PooledByteBufferAllocator.Default.Buffer().WithOrder(ByteOrder.LittleEndian);

            for (var size = mKcp.PeekSize(); size > 0; size = mKcp.PeekSize())
            {
                if (mKcp.Receive(outBuffer) > 0)
                {
                }
            }
        }
Beispiel #8
0
        private static void Receive()
        {
            try
            {
                byte[] data   = new byte[1024];
                int    buflen = socket.ReceiveFrom(data, ref ep);
                Console.WriteLine("收到UDP消息长度{0} IP{1} port{2}", buflen, (ep as IPEndPoint).Address, (ep as IPEndPoint).Port);
                Console.WriteLine("mKcp Input");
                Span <byte> buffer = data;
                mKcp.Input(buffer);

                Receive();
            }
            catch (Exception e)
            {
                Console.WriteLine("[UdpSocket] socket receive error {0}", e.ToString());
            }
        }
Beispiel #9
0
 /// <summary>
 /// Udp 接收数据
 /// </summary>
 private void UdpRecvFunction()
 {
     while (m_isRunning)
     {
         if (udpClient.Available <= 0)
         {
             continue;
         }
         if (udpClient.Client == null)
         {
             return;
         }
         byte[] recvBytes = udpClient.Receive(ref recvEndPoint);
         if (recvBytes.Length == 0)
         {
             break;
         }
         kcpClient.Input(recvBytes);
     }
 }
Beispiel #10
0
        public void TestKCP()
        {
            ///发送次数
            const int echoTimes = 3;
            Random    random    = new Random();

            var handle1 = new Handle();
            var handle2 = new Handle();

            const int conv = 123;
            var       kcp1 = new Kcp(conv, handle1);
            var       kcp2 = new Kcp(conv, handle2);

            ///kcp设置
            ///https://github.com/skywind3000/kcp/issues/39#issuecomment-244592173
            kcp1.NoDelay(1, 10, 2, 1);//fast
            kcp1.WndSize(64, 64);
            kcp1.SetMtu(512);

            kcp2.NoDelay(1, 10, 2, 1);//fast
            kcp2.WndSize(64, 64);
            kcp2.SetMtu(512);

            var sendbyte = Encoding.ASCII.GetBytes(message);

            handle1.Out += buffer =>
            {
                var next = random.Next(100);
                if (next >= 5)///随机丢包
                {
                    kcp2.Input(buffer);
                }
            };

            handle2.Out += buffer =>
            {
                kcp1.Input(buffer);
            };

            int end = 0;

            handle1.Recv += buffer =>
            {
                unsafe
                {
                    using (MemoryHandle p = buffer.Memory.Pin())
                    {
                        var str = Encoding.ASCII.GetString((byte *)p.Pointer, buffer.Memory.Length);
                        Assert.AreEqual(message, str);
                        Interlocked.Increment(ref end);
                        //Assert.Warn($"echo {end}");
                        if (end < echoTimes)
                        {
                            kcp1.Send(buffer.Memory.Span);
                        }
                    }
                }
            };

            handle2.Recv += buffer =>
            {
                kcp2.Send(buffer.Memory.Span);
            };

            Task.Run(async() =>
            {
                try
                {
                    while (true)
                    {
                        kcp1.Update(DateTime.UtcNow);
                        int len;
                        while ((len = kcp1.PeekSize()) > 0)
                        {
                            var buffer = kcp1.CreateBuffer(len);
                            if (kcp1.Recv(buffer.Memory.Span) >= 0)
                            {
                                handle1.Receive(buffer);
                            }
                        }
                        await Task.Delay(5);
                    }
                }
                catch (Exception e)
                {
                    e.ToString();
                }
            });

            Task.Run(async() =>
            {
                try
                {
                    while (true)
                    {
                        kcp2.Update(DateTime.UtcNow);
                        int len;
                        //while ((len = kcp2.PeekSize()) > 0)
                        //{
                        //    var buffer = kcp2.CreateBuffer(len);
                        //    if (kcp2.Recv(buffer.Memory.Span) >= 0)
                        //    {
                        //        handle2.Receive(buffer);
                        //    }
                        //}

                        do
                        {
                            var(buffer, avalidSzie) = kcp2.TryRecv();
                            len = avalidSzie;
                            if (buffer != null)
                            {
                                handle2.Receive(buffer);
                            }
                        } while (len > 0);

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

            kcp1.Send(sendbyte);

            var task = Task.Run(async() =>
            {
                while (end < echoTimes)
                {
                    await Task.Yield();
                }
                return(1);
            });

            task.Result.ToString();
        }
Beispiel #11
0
 public void KcpInput(byte[] datas)
 {
     kcp.Input(datas);
 }
Beispiel #12
0
 public void MockInput(Span <byte> span)
 {
     _kcp.Input(span);
     _needUpdate = true;
 }
 void process_kcpio_queue(object state)
 {
     while (Connected)
     {
         try
         {
             //send process
             snd_queue.DequeueAll(it =>
             {
                 SendPacket(it);
                 //mKcp.Send(it);
             });
             Stopwatch t = new Stopwatch();
             t.Start();
             mKcp.Flush((int)kcpUtil.nowTotalMilliseconds);
             rcv_queue.DequeueAll(it =>
             {
                 mKcp.Input(it);
             });
             rcvCache.Clear();
             //rcvCache.Capacity(peekSize);
             while (true)
             {
                 int peekSize = mKcp.PeekSize();
                 if (peekSize > 0)
                 {
                     int rcvSize = mKcp.Receive(rcvCache);
                     if (rcvSize > 0)
                     {
                         //packer.Recv(rcvCache);
                         Unpack(rcvCache);
                     }
                     else
                     {
                         break;
                     }
                 }
                 else
                 {
                     break;
                 }
             }
             t.Stop();
             if (t.ElapsedMilliseconds > 5)
             {
                 Console.WriteLine(string.Format("used time:{0}", t.ElapsedMilliseconds));
             }
         }
         catch (Exception e)
         {
             Console.WriteLine(e.ToString());
         }
         finally
         {
             //Console.WriteLine("thread run error");
         }
         if (kcpThreadNotify.WaitOne(5))
         {
             Thread.Sleep(2);
         }
     }
 }
Beispiel #14
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);
        }
Beispiel #15
0
        public static void Main(string[] args)
        {
            Console.WriteLine(ShowThread);
            Random random = new Random();

            var handle1 = new Handle();
            var handle2 = new Handle();

            const int conv = 123;
            var       kcp1 = new Kcp(conv, handle1);
            var       kcp2 = new Kcp(conv, handle2);

            kcp1.NoDelay(1, 10, 2, 1);//fast
            kcp1.WndSize(64, 64);
            kcp1.SetMtu(512);

            kcp2.NoDelay(1, 10, 2, 1);//fast
            kcp2.WndSize(64, 64);
            kcp2.SetMtu(512);

            var sendbyte = Encoding.ASCII.GetBytes(TestClass.message);

            handle1.Out += buffer =>
            {
                var next = random.Next(100);
                if (next >= 15)///随机丢包
                {
                    //Console.WriteLine($"11------Thread[{Thread.CurrentThread.ManagedThreadId}]");
                    Task.Run(() =>
                    {
                        //Console.WriteLine($"12------Thread[{Thread.CurrentThread.ManagedThreadId}]");
                        kcp2.Input(buffer.Span);
                    });
                }
                else
                {
                    //Console.WriteLine("Send miss");
                }
            };

            handle2.Out += buffer =>
            {
                var next = random.Next(100);
                if (next >= 0)///随机丢包
                {
                    Task.Run(() =>
                    {
                        kcp1.Input(buffer.Span);
                    });
                }
                else
                {
                    Console.WriteLine("Resp miss");
                }
            };
            int count = 0;

            handle1.Recv += buffer =>
            {
                var str = Encoding.ASCII.GetString(buffer);
                count++;
                if (TestClass.message == str)
                {
                    kcptest.Log1($"kcp  echo----{count}");
                }
                var res = kcp1.Send(buffer);
                if (res != 0)
                {
                    kcptest.Log1($"kcp send error");
                }
            };

            int recvCount = 0;

            handle2.Recv += buffer =>
            {
                recvCount++;
                kcptest.Log2($"kcp2 recv----{recvCount}");
                var res = kcp2.Send(buffer);
                if (res != 0)
                {
                    kcptest.Log2($"kcp send error");
                }
            };

            Task.Run(async() =>
            {
                try
                {
                    int updateCount = 0;
                    while (true)
                    {
                        kcp1.Update(DateTime.UtcNow);

                        int len;
                        while ((len = kcp1.PeekSize()) > 0)
                        {
                            var buffer = new byte[len];
                            if (kcp1.Recv(buffer) >= 0)
                            {
                                handle1.Receive(buffer);
                            }
                        }

                        await Task.Delay(5);
                        updateCount++;
                        if (updateCount % 1000 == 0)
                        {
                            Console.WriteLine($"KCP1 ALIVE {updateCount}----{ShowThread}");
                        }
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                }
            });

            Task.Run(async() =>
            {
                try
                {
                    int updateCount = 0;
                    while (true)
                    {
                        kcp2.Update(DateTime.UtcNow);

                        //var utcNow = DateTime.UtcNow;
                        //var res = kcp2.Check(utcNow);

                        int len;
                        do
                        {
                            var(buffer, avalidSzie) = kcp2.TryRecv();
                            len = avalidSzie;
                            if (buffer != null)
                            {
                                var temp = new byte[len];
                                buffer.Memory.Span.Slice(0, len).CopyTo(temp);
                                handle2.Receive(temp);
                            }
                        } while (len > 0);

                        await Task.Delay(5);
                        updateCount++;
                        if (updateCount % 1000 == 0)
                        {
                            Console.WriteLine($"KCP2 ALIVE {updateCount}----{ShowThread}");
                        }
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                }
            });

            kcp1.Send(sendbyte);
        }
Beispiel #16
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
                    {
                    }
                }
            }
                );
        }