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); } }); }
public void MockInput(Span <byte> span) { var next = random.Next(100); if (next >= 0)///随机丢包 { _kcp.Input(span); } }
/// <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); } }
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(); } } }
/// <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); } }
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) { } } }
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()); } }
/// <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); } }
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(); }
public void KcpInput(byte[] datas) { kcp.Input(datas); }
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); } } }
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); }
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); }
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 { } } } ); }