private async Task UdpReceive(Socket socket, IVirtualChannel channel) { var remoteEndPoint = new IPEndPoint(IPAddress.Any, 4040); while (true) { var buffer = _bufferPool.Rent(1024 * 5); try { var result = await socket .ReceiveFromAsync(new ArraySegment <byte>(buffer, 0, buffer.Length), SocketFlags.None, remoteEndPoint) .ConfigureAwait(false); await channel.WritePipeDataAsync((new ArraySegment <byte>(buffer, 0, result.ReceivedBytes)).AsMemory(), CancellationToken.None); } catch (NullReferenceException) { break; } catch (ObjectDisposedException) { break; } finally { _bufferPool.Return(buffer); } } }
private async Task KeepAccept(Socket listenSocket) { while (!_cancellationTokenSource.IsCancellationRequested) { var buffer = default(byte[]); try { var bufferSize = ChannelOptions.MaxPackageLength; buffer = _bufferPool.Rent(bufferSize); var result = await listenSocket .ReceiveFromAsync(new ArraySegment <byte>(buffer, 0, buffer.Length), SocketFlags.None, _acceptRemoteEndPoint) .ConfigureAwait(false); var packageData = new ArraySegment <byte>(buffer, 0, result.ReceivedBytes); var remoteEndPoint = result.RemoteEndPoint as IPEndPoint; var sessionID = _udpSessionIdentifierProvider.GetSessionIdentifier(remoteEndPoint, packageData); var session = await _sessionContainer.GetSessionByIDAsync(sessionID); IVirtualChannel channel = null; if (session != null) { channel = session.Channel as IVirtualChannel; } else { channel = await CreateChannel(_listenSocket, remoteEndPoint, sessionID); if (channel == null) { return; } OnNewClientAccept(channel); } await channel.WritePipeDataAsync(packageData.AsMemory(), _cancellationTokenSource.Token); } catch (Exception e) { if (e is ObjectDisposedException || e is NullReferenceException) { break; } if (e is SocketException se) { var errorCode = se.ErrorCode; //The listen socket was closed if (errorCode == 125 || errorCode == 89 || errorCode == 995 || errorCode == 10004 || errorCode == 10038) { break; } } _logger.LogError(e, $"Listener[{this.ToString()}] failed to receive udp data"); } finally { _bufferPool.Return(buffer); } } _stopTaskCompletionSource.TrySetResult(true); }