/// <summary> /// The run function for the connection listener thread. /// </summary> private void ConnectionListenerThreadRun() { while (_childThreadsRunning) { try { var incomingTcpClient = _connectionListener.AcceptTcpClient(); var ipEndPoint = (IPEndPoint)incomingTcpClient.Client.RemoteEndPoint; var incomingNodeProperties = new NodeProperties(ipEndPoint.Address.MapToIPv4(), ipEndPoint.Port); _logger.Write("Connection received from " + incomingNodeProperties, LogLevels.Info); lock (_receivingLockObject) { _receivingConnections[incomingNodeProperties] = new NetworkConnection { Client = incomingTcpClient, LastPingReceived = DateTime.UtcNow }; } } catch (Exception) { // Assuming the error was because we are stopping accepting connections or it // was a connection error in which case it can be retried. } } }
/// <summary> /// Gets a network connection to the specified node, creating the connection if need be. /// </summary> /// <param name="connectTo">The node to connect to.</param> /// <returns> /// The network connection associated with that node, or null if it could not be created. /// </returns> protected async Task<NetworkConnection> GetUnapprovedNetworkConnection(NodeProperties connectTo) { bool reconnect; lock (_sendingLockObject) { reconnect = !_sendingConnections.ContainsKey(connectTo); if (reconnect) { _sendingConnections[connectTo] = null; } } if (reconnect) { TcpClient client = null; try { _logger.Write("Attempting connection to " + connectTo, LogLevels.Info); client = new TcpClient(); client.NoDelay = true; await client.ConnectAsync(connectTo.IpAddress, connectTo.Port).ConfigureAwait(false); NetworkConnection connection = new NetworkConnection { Client = client, LastPingReceived = DateTime.UtcNow }; lock (_sendingLockObject) { _sendingConnections[connectTo] = connection; } _logger.Write("Connection to " + connectTo + " successful", LogLevels.Info); return connection; } catch { _logger.Write("Connection to " + connectTo + " failed", LogLevels.Warning); if (client != null) { client.Close(); } lock (_sendingLockObject) { NodeDisconnected(connectTo); } return null; } } bool waiting; lock (_sendingLockObject) { waiting = _sendingConnections[connectTo] == null; } while (waiting) { await Task.Delay(1).ConfigureAwait(false); lock (_sendingLockObject) { waiting = _sendingConnections.ContainsKey(connectTo) && _sendingConnections[connectTo] == null; } } lock (_sendingLockObject) { return !_sendingConnections.ContainsKey(connectTo) ? null : _sendingConnections[connectTo]; } }