示例#1
0
        private async Task ParseCmd(ReadOnlyMemory <byte> recvBufMemory, int length)
        {
            byte cmd = recvBufMemory.Span[0];

            if ((cmd & NetworkCmd.SYN) != 0)
            {
                if ((cmd & NetworkCmd.ACK) != 0)
                {
                    //  Debug.LogFormat("recv SYN +ACK");
                    //  syn ack
                    uint conv = BinaryPrimitives.ReadUInt32LittleEndian(recvBufMemory.Span.Slice(1));
                    if (_kcpLink == null)
                    {
                        _kcpLink = new KcpLink();
                        _kcpLink.Run(conv, new KcpUdpCallback(_socket, _remoteEP));
                        _kcpLink.OnRecvKcpPackage += KcpLink_OnRecvKcpPackage;
                    }
                    //  发送 ayn ack
                    var sendBytes = new byte[5];
                    sendBytes[0] = NetworkCmd.SYN | NetworkCmd.ACK;
                    BinaryPrimitives.WriteUInt32LittleEndian(new Span <byte>(sendBytes, 1, 4), conv);
                    //  Debug.LogFormat("send SYN + ACK");
                    _socket.Send(sendBytes, SocketFlags.None);
                    _synTaskCancellationTokenSource.Cancel();
                }
                else
                {
                    // syn 客户端不存在这种情况
                }
            }
            else if ((cmd & NetworkCmd.PUSH) != 0)
            {
                //  Debug.LogFormat("recv PUSH");
                await _kcpLink.RecvFromRemoteAsync(recvBufMemory.Slice(1, length - 1));
            }
            else if ((cmd & NetworkCmd.FIN) != 0)
            {
                //  Debug.LogFormat("recv FIN");
                _kcpLink.Stop();
            }
        }
示例#2
0
        private async Task ParseCmd(NetworkPackage package)
        {
            ReadOnlyMemory <byte> buffer = package.MemoryOwner.Memory.Slice(0, package.Lenght);
            byte cmd = buffer.Span[0];

            if ((cmd & NetworkCmd.SYN) != 0)
            {
                if ((cmd & NetworkCmd.ACK) == 0)
                {
                    //  Debug.LogFormat("recv SYN", package.Remote);
                    //  连接请求 syn
                    //  TODO 验证IdToken,返回 对应的 conv
                    uint conv = 1;
                    if (package.Remote is IPEndPoint ip)
                    {
                        //  先用对方的Port作为连接号吧
                        conv = (uint)ip.Port;
                    }

                    var remote = package.Remote;
                    if (!_synAckTaskTokens.ContainsKey(remote))
                    {
                        var cancellationTokenSource = new CancellationTokenSource();
                        if (_synAckTaskTokens.TryAdd(remote, cancellationTokenSource))
                        {
                            var synAck = new Task(async() => {
                                var sendBytes = new byte[5];
                                sendBytes[0]  = NetworkCmd.SYN | NetworkCmd.ACK;
                                BinaryPrimitives.WriteUInt32LittleEndian(new Span <byte>(sendBytes, 1, 4), conv);
                                int delay = InitalTimeOut;
                                do
                                {
                                    //  发送conv
                                    //  Debug.LogFormat("send SYN + ACK", package.Remote);
                                    _socket.SendTo(sendBytes, SocketFlags.None, remote);
                                    try {
                                        await Task.Delay(delay, cancellationTokenSource.Token);
                                    }
                                    catch (TaskCanceledException) {
                                        break;
                                    }
                                    delay = (int)(delay * Rate);
                                } while (!cancellationTokenSource.IsCancellationRequested);
                                _synAckTaskTokens.TryRemove(remote, out var token);
                            });
                            synAck.Start();
                        }
                    }
                }
                else
                {
                    //  Debug.LogFormat("recv SYN + ACK", package.Remote);
                    var conv   = BinaryPrimitives.ReadUInt32LittleEndian(buffer.Span.Slice(1));
                    var remote = package.Remote;
                    //  连接确认 syn ack
                    if (_synAckTaskTokens.TryRemove(package.Remote, out var token))
                    {
                        //  移除旧连接
                        if (_networkLinks.TryRemove(package.Remote, out var link))
                        {
                            link.Stop();
                        }
                        //  建立连接
                        link = new KcpLink();
                        link.OnRecvKcpPackage += Link_OnRecvKcpPackage;
                        var kcpOutPut = new KcpUdpCallback(_socket, package.Remote, _networkLinks);
                        link.Run(conv, kcpOutPut);
                        _networkLinks.TryAdd(package.Remote, link);
                        token.Cancel();
                    }
                    else
                    {
                        if (_networkLinks.TryGetValue(package.Remote, out var link))
                        {
                            if (link.Conv != conv)
                            {
                                //  连接号已被重置,需要重新请求连接
                                var sendBytes = new byte[1];
                                sendBytes[0] = NetworkCmd.RESET;
                                //  Debug.LogFormat("send RESET", package.Remote);
                                _socket.SendTo(sendBytes, SocketFlags.None, remote);
                            }
                        }
                        else
                        {
                            //  连接已不存在,需要重新请求连接
                            var sendBytes = new byte[1];
                            sendBytes[0] = NetworkCmd.RESET;
                            //  Debug.LogFormat("send RESET", package.Remote);
                            _socket.SendTo(sendBytes, SocketFlags.None, remote);
                        }
                    }
                }
                package.MemoryOwner.Dispose();
            }
            else if ((cmd & NetworkCmd.PUSH) != 0)
            {
                //  Debug.LogFormat("recv PUSH");
                //  数据
                if (_networkLinks.TryGetValue(package.Remote, out var link))
                {
                    await link.RecvFromRemoteAsync(package.MemoryOwner, 1, package.Lenght - 1);
                }
                else
                {
                    package.MemoryOwner.Dispose();
                }
            }
            else if ((cmd & NetworkCmd.FIN) != 0)
            {
                //  Debug.LogFormat("recv FIN");
                //  断开连接
                if (_networkLinks.TryRemove(package.Remote, out var link))
                {
                    link.Stop();
                }
                package.MemoryOwner.Dispose();
            }
            else
            {
                package.MemoryOwner.Dispose();
            }
        }