private async Task AcceptClientConnectionsAsync(CancellationToken cancellationToken) { while (!cancellationToken.IsCancellationRequested) { try { var clientSocket = await PlatformAbstractionLayer.AcceptAsync(_socket).ConfigureAwait(false); if (clientSocket == null) { continue; } Task.Run(() => TryHandleClientConnectionAsync(clientSocket), cancellationToken).Forget(_logger); } catch (OperationCanceledException) { } catch (Exception exception) { if (exception is SocketException socketException) { if (socketException.SocketErrorCode == SocketError.ConnectionAborted || socketException.SocketErrorCode == SocketError.OperationAborted) { continue; } } _logger.Error(exception, $"Error while accepting connection at TCP listener {_localEndPoint} TLS={_tlsCertificate != null}."); await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken).ConfigureAwait(false); } } }
public async Task ConnectAsync(CancellationToken cancellationToken) { Socket socket; if (_options.AddressFamily == AddressFamily.Unspecified) { socket = new Socket(SocketType.Stream, ProtocolType.Tcp); } else { socket = new Socket(_options.AddressFamily, SocketType.Stream, ProtocolType.Tcp); } socket.ReceiveBufferSize = _options.BufferSize; socket.SendBufferSize = _options.BufferSize; socket.NoDelay = _options.NoDelay; if (_options.DualMode.HasValue) { // It is important to avoid setting the flag if no specific value is set by the user // because on IPv4 only networks the setter will always throw an exception. Regardless // of the actual value. socket.DualMode = _options.DualMode.Value; } // Workaround for: workaround for https://github.com/dotnet/corefx/issues/24430 using (cancellationToken.Register(() => socket.Dispose())) { await PlatformAbstractionLayer.ConnectAsync(socket, _options.Server, _options.GetPort()).ConfigureAwait(false); } var networkStream = new NetworkStream(socket, true); if (_options.TlsOptions.UseTls) { var sslStream = new SslStream(networkStream, false, InternalUserCertificateValidationCallback); _stream = sslStream; await sslStream.AuthenticateAsClientAsync(_options.Server, LoadCertificates(), _options.TlsOptions.SslProtocol, !_options.TlsOptions.IgnoreCertificateRevocationErrors).ConfigureAwait(false); } else { _stream = networkStream; } Endpoint = socket.RemoteEndPoint?.ToString(); }