protected override async Task ConnectImpl(CancellationToken cancellationToken = default(CancellationToken)) { if (IsListenerConnection) { throw new InvalidOperationException($"{this}: Cannot call {nameof(Connect)}"); } Log.Info($"{this}: Starting to {nameof(Connect)} to {RemoteAddress}..."); var hostParts = RemoteAddress.Split(':'); if (hostParts.Length != 2) { throw new FormatException($"{this}: {nameof(RemoteAddress)} is in the wrong format '{RemoteAddress}.' Should be in the format 'hostname:port' for example 'localhost:4356' or 'jumbo.fried.jims.aquarium:4453'"); } var host = hostParts[0]; var port = int.Parse(hostParts[1]); Log.Info($"{this}: Resolving IPAddresses for {host}..."); IPAddress[] addresses = null; cancellationToken.ThrowIfCancellationRequested(); await ResilliantTask.Run(async() => addresses = await Dns.GetHostAddressesAsync(host), cancellationToken : cancellationToken); cancellationToken.ThrowIfCancellationRequested(); addresses = addresses ?? new IPAddress[0]; Log.Info($"{this}: Found {addresses.Length.ToString()}: {string.Join(", ", (object[])addresses)}"); if (addresses.Length == 0) { throw new InvalidOperationException($"Unable to find any IP address for host {host} :("); } foreach (var address in addresses) { try { Log.Info($"{this}: Trying to connect to {address}:{port}..."); cancellationToken.ThrowIfCancellationRequested(); await _client.ConnectAsync(address, port); _clientStream = _client.GetStream() ?? throw new InvalidOperationException("Null stream " + nameof(_client) + "." + nameof(_client.GetStream)); Log.Info($"{this}: Connected to {address}:{port}..."); return; } catch (Exception ex) { Log.Warn($"{this}: Error connecting to {RemoteAddress} using the address {address}", ex); } } throw new CouldNotConnectException($"{this}: Unable to connect to host {host}. Check logs for previous errors."); }