/// <summary> /// Connect to the given IP address using the port specified as part of the network parameters. Once construction /// is complete a functioning network channel is set up and running. /// </summary> /// <param name="peerAddress">IP address to connect to. IPv6 is not currently supported by BitCoin. If port is not positive the default port from params is used.</param> /// <param name="networkParams">Defines which network to connect to and details of the protocol.</param> /// <param name="bestHeight">How many blocks are in our best chain</param> /// <param name="connectTimeout">Timeout in milliseconds when initially connecting to peer</param> /// <exception cref="IOException">If there is a network related failure.</exception> /// <exception cref="ProtocolException">If the version negotiation failed.</exception> public NetworkConnection(PeerAddress peerAddress, NetworkParameters networkParams, uint bestHeight, int connectTimeout) { _params = networkParams; remoteIp = peerAddress.Addr; var port = (peerAddress.Port > 0) ? peerAddress.Port : networkParams.Port; var address = new IPEndPoint(remoteIp, port); _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); _socket.Connect(address); _socket.SendTimeout = _socket.ReceiveTimeout = connectTimeout; _out = new NetworkStream(_socket, FileAccess.Write); _in = new NetworkStream(_socket, FileAccess.Read); // the version message never uses check-summing. Update check-summing property after version is read. serializer = new BitcoinSerializer(networkParams, true); // SDL: Checksuming now ALWAYS necessary versionMessage = Handshake(networkParams, bestHeight); // newer clients use check-summing serializer.UseChecksumming(versionMessage.ClientVersion >= 209); // Handshake is done! }