using System; using System.Buffers; using System.Net; using System.Net.Sockets; using System.Net.Sockets.Kcp; using System.Threading; using System.Threading.Tasks; using Fort23.UTool; public class UDPForKCP : IKcpCallback, IDisposable { private UdpClient client; private Thread _udpClientThread; public int myPort; public int ycPort; public bool isLockSend; public object LockObject; public bool isConnect; // public int PiPeiPort; public UDPForKCP() { } public UDPForKCP(int port, uint conv) : this(port, null, conv) { } public UDPForKCP(int port, IPEndPoint endPoint, uint conv) { myPort = port; // LogTool.Log("链接端口"+port+"__"+endPoint.Address); client = new UdpClient(port); if (endPoint != null) { client.Connect(endPoint); isConnect = true; } _kcp = new SimpleSegManager.Kcp(conv, this); kcp.NoDelay(1, 40, 2, 0); this.EndPoint = endPoint; _udpClientThread = new Thread(BeginRecv); _udpClientThread.Start(); } public SimpleSegManager.Kcp kcp { get { return _kcp; } } public IPEndPoint EndPoint { get; set; } private SimpleSegManager.Kcp _kcp; public void Output(IMemoryOwner buffer, int avalidLength) { if (EndPoint == null) { return; } var s = buffer.Memory.Span.Slice(0, avalidLength).ToArray(); if (isLockSend) { lock (LockObject) { client.Send(s, s.Length, EndPoint); // Debug.Log("发送"+client.Client.RemoteEndPoint); buffer.Dispose(); } } else { // Debug.Log("发送"+client.Client.RemoteEndPoint!=null); if (isConnect) { client.Send(s, s.Length); } else { client.Send(s, s.Length, EndPoint); } buffer.Dispose(); } } public async void SendAsync(byte[] datagram, int bytes) { int c = kcp.Send(datagram.AsSpan().Slice(0, bytes)); // LogTool.Error("发送错误" + c); } public byte[] ReceiveAsync() { var (buffer, avalidLength) = kcp.TryRecv(); while (buffer == null) { Thread.Sleep(5); if (_udpClientThread == null) { return null; } (buffer, avalidLength) = kcp.TryRecv(); } var s = buffer.Memory.Span.Slice(0, avalidLength).ToArray(); return s; } private async void BeginRecv() { while (_udpClientThread != null) { try { var res = await client.ReceiveAsync(); int ok = kcp.Input(res.Buffer); if (ok >= 0) { EndPoint = res.RemoteEndPoint; ycPort = EndPoint.Port; } else { LogTool.Error("kcp.Receive 返回错误" + ok+"___"+res.RemoteEndPoint); } } catch (Exception e) { SocketException socketException = e as SocketException; if (socketException.ErrorCode == 10054) { } LogTool.Error(e); } Thread.Sleep(1); } } public void Dispose() { _udpClientThread = null; client?.Dispose(); kcp?.Dispose(); client = null; _kcp = null; } }