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(); } }
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(); } }