private async Task AcceptConnections() { while (!_listenerToken.IsCancellationRequested) { ClientMetadata client = null; try { TcpClient tcpClient = await _listener.AcceptTcpClientAsync().ConfigureAwait(false); string clientIp = tcpClient.Client.RemoteEndPoint.ToString(); client = new ClientMetadata(tcpClient); if (_ssl) { if (_settings.AcceptInvalidCertificates) { client.SslStream = new SslStream(client.NetworkStream, false, new RemoteCertificateValidationCallback(AcceptCertificate)); } else { client.SslStream = new SslStream(client.NetworkStream, false); } bool success = await StartTls(client).ConfigureAwait(false); if (!success) { client.Dispose(); continue; } } _clients.TryAdd(clientIp, client); _clientsLastSeen.TryAdd(clientIp, DateTime.Now); Logger?.Invoke($"{_header}starting data receiver for: {clientIp}"); _events.HandleClientConnected(this, new ConnectionEventArgs(clientIp)); if (_keepalive.EnableTcpKeepAlives) { EnableKeepalives(tcpClient); } CancellationTokenSource linkedCts = CancellationTokenSource.CreateLinkedTokenSource(client.Token, _token); Task unawaited = Task.Run(() => DataReceiver(client), linkedCts.Token); } catch (Exception ex) { if (ex is TaskCanceledException || ex is OperationCanceledException || ex is ObjectDisposedException || ex is InvalidOperationException) { _isListening = false; if (client != null) { client.Dispose(); } Logger?.Invoke($"{_header}stopped listening"); break; } else { if (client != null) { client.Dispose(); } Logger?.Invoke($"{_header}exception while awaiting connections: {ex}"); continue; } } } _isListening = false; }
private async Task SendInternalAsync(string ipPort, long contentLength, Stream stream, CancellationToken token) { ClientMetadata client = null; try { if (!_clients.TryGetValue(ipPort, out client)) { return; } if (client == null) { return; } long bytesRemaining = contentLength; int bytesRead = 0; byte[] buffer = new byte[_settings.StreamBufferSize]; await client.SendLock.WaitAsync(token).ConfigureAwait(false); while (bytesRemaining > 0) { bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length, token).ConfigureAwait(false); if (bytesRead > 0) { if (!_ssl) { await client.NetworkStream.WriteAsync(buffer, 0, bytesRead, token).ConfigureAwait(false); } else { await client.SslStream.WriteAsync(buffer, 0, bytesRead, token).ConfigureAwait(false); } bytesRemaining -= bytesRead; _statistics.SentBytes += bytesRead; } } if (!_ssl) { await client.NetworkStream.FlushAsync(token).ConfigureAwait(false); } else { await client.SslStream.FlushAsync(token).ConfigureAwait(false); } _events.HandleDataSent(this, new DataSentEventArgs(ipPort, contentLength)); } catch (TaskCanceledException) { } catch (OperationCanceledException) { } finally { if (client != null) { client.SendLock.Release(); } } }