private KCPHandle CreateKcp(uint connectionId, KCPSetting setting)
        {
            KCPHandle handle = new KCPHandle(dataSocket, connectionId);

            handle.kcp.NoDelay(setting.noDelay, setting.interval, setting.resend, setting.noCongestion);
            handle.kcp.WndSize(setting.sendWindowSize, setting.receiveWindowSize);
            handle.kcp.SetMtu(setting.mtu);
            return(handle);
        }
        private void RecvData()
        {
            if (dataSocket == null)
            {
                return;
            }

            if (!dataSocket.Poll(0, SelectMode.SelectRead))
            {
                return;
            }

            EndPoint endPoint = new IPEndPoint(IPAddress.Any, 0);
            int      recvLength;

            try
            {
                recvLength = dataSocket.ReceiveFrom(recvBuffer, 0, recvBuffer.Length, SocketFlags.None, ref endPoint);
            }
            catch (SocketException ex)
            {
                HandleError(endPoint, ex.SocketErrorCode);
                return;
            }

            recvReader.Clear();
            recvReader.SetSource(recvBuffer, 0, recvLength);
            uint connectionId = recvReader.GetUInt();
            // Have to find which kcp send this data, then set its input
            KCPHandle kcpHandle = null;

            if (kcpHandles.TryGetValue(connectionId, out kcpHandle))
            {
                kcpHandle.remoteEndPoint = endPoint;
                kcpHandle.kcp.Input(new Span <byte>(recvBuffer, 0, recvLength));

                byte[] kcpData;
                while ((recvLength = kcpHandle.kcp.PeekSize()) > 0)
                {
                    kcpData = new byte[recvLength];
                    if (kcpHandle.kcp.Recv(kcpData) >= 0)
                    {
                        TransportEventData eventData = default(TransportEventData);
                        eventData.connectionId = connectionId;
                        eventData.endPoint     = (IPEndPoint)endPoint;
                        HandleRecvData(kcpData, recvLength, eventData);
                    }
                }
            }
        }