private Task ConnectAsyncCore(IPAddress[] addresses, int port) { // Validate the args, similar to how Socket.Connect(IPAddress[], int) would. if (addresses == null) { throw new ArgumentNullException(nameof(addresses)); } if (addresses.Length == 0) { throw new ArgumentException(SR.net_invalidAddressList, nameof(addresses)); } if (!TcpValidationHelpers.ValidatePortNumber(port)) { throw new ArgumentOutOfRangeException(nameof(port)); } // If the client socket has already materialized, this API can't be used. // Similarly if another operation to set the socket is already in progress. if (_clientSocket != null) { throw new PlatformNotSupportedException(SR.net_sockets_connect_multiaddress_notsupported); } // Do the real work. EnterClientLock(); return(ConnectAsyncCorePrivate(addresses, port)); }
// This creates a TcpListener that listens on both IPv4 and IPv6 on the given port. public static TcpListener Create(int port) { if (NetEventSource.IsEnabled) { NetEventSource.Enter(null, port); } if (!TcpValidationHelpers.ValidatePortNumber(port)) { throw new ArgumentOutOfRangeException(nameof(port)); } TcpListener listener; if (Socket.OSSupportsIPv6) { // If OS supports IPv6 use dual mode so both address families work. listener = new TcpListener(IPAddress.IPv6Any, port); listener.Server.DualMode = true; } else { // If not, fall-back to old IPv4. listener = new TcpListener(IPAddress.Any, port); } if (NetEventSource.IsEnabled) { NetEventSource.Exit(null, port); } return(listener); }
// Connects the Client to the specified port on the specified host. public void Connect(IPAddress address, int port) { if (Logging.On) { Logging.Enter(Logging.Sockets, this, "Connect", address); } if (_cleanedUp) { throw new ObjectDisposedException(this.GetType().FullName); } if (address == null) { throw new ArgumentNullException("address"); } if (!TcpValidationHelpers.ValidatePortNumber(port)) { throw new ArgumentOutOfRangeException("port"); } IPEndPoint remoteEP = new IPEndPoint(address, port); Connect(remoteEP); if (Logging.On) { Logging.Exit(Logging.Sockets, this, "Connect", null); } }
// Connects the Client to the specified port on the specified host. public void Connect(IPAddress address, int port) { if (NetEventSource.Log.IsEnabled()) { NetEventSource.Enter(this, address); } ThrowIfDisposed(); if (address == null) { throw new ArgumentNullException(nameof(address)); } if (!TcpValidationHelpers.ValidatePortNumber(port)) { throw new ArgumentOutOfRangeException(nameof(port)); } IPEndPoint remoteEP = new IPEndPoint(address, port); Connect(remoteEP); if (NetEventSource.Log.IsEnabled()) { NetEventSource.Exit(this); } }
// Connects the Client to the specified port on the specified host. public void Connect(IPAddress address, int port) { if (NetEventSource.IsEnabled) { NetEventSource.Enter(this, address); } if (_cleanedUp) { throw new ObjectDisposedException(GetType().FullName); } if (address == null) { throw new ArgumentNullException(nameof(address)); } if (!TcpValidationHelpers.ValidatePortNumber(port)) { throw new ArgumentOutOfRangeException(nameof(port)); } IPEndPoint remoteEP = new IPEndPoint(address, port); Connect(remoteEP); if (NetEventSource.IsEnabled) { NetEventSource.Exit(this); } }
// Initializes a new instance of the System.Net.Sockets.TcpClient class and connects to the specified port on // the specified host. public TcpClient(string hostname, int port) { if (NetEventSource.IsEnabled) { NetEventSource.Enter(this, hostname); } if (hostname == null) { throw new ArgumentNullException(nameof(hostname)); } if (!TcpValidationHelpers.ValidatePortNumber(port)) { throw new ArgumentOutOfRangeException(nameof(port)); } try { Connect(hostname, port); } catch { _clientSocket?.Close(); throw; } if (NetEventSource.IsEnabled) { NetEventSource.Exit(this); } }
// Initializes a new instance of the System.Net.Sockets.TcpClient class and connects to the specified port on // the specified host. public TcpClient(string hostname, int port) { if (NetEventSource.Log.IsEnabled()) { NetEventSource.Info(this, hostname); } if (hostname == null) { throw new ArgumentNullException(nameof(hostname)); } if (!TcpValidationHelpers.ValidatePortNumber(port)) { throw new ArgumentOutOfRangeException(nameof(port)); } _family = AddressFamily.Unknown; try { Connect(hostname, port); } catch { _clientSocket?.Close(); throw; } }
// Creates a new instance of the UdpClient class that communicates on the // specified port number. public UdpClient(int port, AddressFamily family) { // Validate input parameters. if (!TcpValidationHelpers.ValidatePortNumber(port)) { throw new ArgumentOutOfRangeException(nameof(port)); } // Validate the address family. if (family != AddressFamily.InterNetwork && family != AddressFamily.InterNetworkV6) { throw new ArgumentException(SR.Format(SR.net_protocol_invalid_family, "UDP"), nameof(family)); } IPEndPoint localEP; _family = family; if (_family == AddressFamily.InterNetwork) { localEP = new IPEndPoint(IPAddress.Any, port); } else { localEP = new IPEndPoint(IPAddress.IPv6Any, port); } CreateClientSocket(); _clientSocket.Bind(localEP); }
public TcpListener(int port) { if (!TcpValidationHelpers.ValidatePortNumber(port)) { throw new ArgumentOutOfRangeException(nameof(port)); } _serverSocketEP = new IPEndPoint(IPAddress.Any, port); _serverSocket = new Socket(_serverSocketEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp); }
// Connects the Client to the specified port on the specified host. public void Connect(IPAddress address, int port) { ThrowIfDisposed(); ArgumentNullException.ThrowIfNull(address); if (!TcpValidationHelpers.ValidatePortNumber(port)) { throw new ArgumentOutOfRangeException(nameof(port)); } IPEndPoint remoteEP = new IPEndPoint(address, port); Connect(remoteEP); }
// Connects the Client to the specified port on the specified host. public void Connect(string hostname, int port) { ThrowIfDisposed(); ArgumentNullException.ThrowIfNull(hostname); if (!TcpValidationHelpers.ValidatePortNumber(port)) { throw new ArgumentOutOfRangeException(nameof(port)); } Client.Connect(hostname, port); _family = Client.AddressFamily; _active = true; }
public UdpClient(string hostname, int port) { ArgumentNullException.ThrowIfNull(hostname); if (!TcpValidationHelpers.ValidatePortNumber(port)) { throw new ArgumentOutOfRangeException(nameof(port)); } // NOTE: Need to create different kinds of sockets based on the addresses // returned from DNS. As a result, we defer the creation of the // socket until the Connect method. Connect(hostname, port); }
// Initializes a new instance of the TcpListener class that listens to the specified IP address // and port. public TcpListener(IPAddress localaddr, int port) { if (NetEventSource.Log.IsEnabled()) { NetEventSource.Info(this, localaddr); } ArgumentNullException.ThrowIfNull(localaddr); if (!TcpValidationHelpers.ValidatePortNumber(port)) { throw new ArgumentOutOfRangeException(nameof(port)); } _serverSocketEP = new IPEndPoint(localaddr, port); _serverSocket = new Socket(_serverSocketEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp); }
public void Connect(IPAddress addr, int port) { ThrowIfDisposed(); if (addr == null) { throw new ArgumentNullException(nameof(addr)); } if (!TcpValidationHelpers.ValidatePortNumber(port)) { throw new ArgumentOutOfRangeException(nameof(port)); } IPEndPoint endPoint = new IPEndPoint(addr, port); Connect(endPoint); }
public void Connect(IPAddress addr, int port) { if (_cleanedUp) { throw new ObjectDisposedException(this.GetType().FullName); } if (addr == null) { throw new ArgumentNullException(nameof(addr)); } if (!TcpValidationHelpers.ValidatePortNumber(port)) { throw new ArgumentOutOfRangeException(nameof(port)); } IPEndPoint endPoint = new IPEndPoint(addr, port); Connect(endPoint); }
// Initializes a new instance of the System.Net.Sockets.TcpClient class and connects to the // specified port on the specified host. public TcpClient(string hostname, int port) { if (Logging.On) { Logging.Enter(Logging.Sockets, this, "TcpClient", hostname); } if (hostname == null) { throw new ArgumentNullException("hostname"); } if (!TcpValidationHelpers.ValidatePortNumber(port)) { throw new ArgumentOutOfRangeException("port"); } // IPv6: Delay creating the client socket until we have // performed DNS resolution and know which address // families we can use. try { Connect(hostname, port); } catch (Exception e) { if (e is OutOfMemoryException) { throw; } if (_clientSocket != null) { _clientSocket.Dispose(); } throw e; } if (Logging.On) { Logging.Exit(Logging.Sockets, this, "TcpClient", null); } }
private void StartConnectCore(string host, int port) { // Validate the args, similar to how Socket.Connect(string, int) would. if (host == null) { throw new ArgumentNullException(nameof(host)); } if (!TcpValidationHelpers.ValidatePortNumber(port)) { throw new ArgumentOutOfRangeException(nameof(port)); } // If the client socket has already materialized, this API can't be used. if (_clientSocket != null) { throw new PlatformNotSupportedException(SR.net_sockets_connect_multiaddress_notsupported); } EnterClientLock(); }
// Initializes a new instance of the System.Net.Sockets.TcpClient class and connects to the specified port on // the specified host. public TcpClient(string hostname, int port) { if (NetEventSource.Log.IsEnabled()) { NetEventSource.Enter(NetEventSource.ComponentType.Socket, this, nameof(TcpClient), hostname); } if (hostname == null) { throw new ArgumentNullException(nameof(hostname)); } if (!TcpValidationHelpers.ValidatePortNumber(port)) { throw new ArgumentOutOfRangeException(nameof(port)); } // IPv6: Delay creating the client socket until we have // performed DNS resolution and know which address // families we can use. try { Connect(hostname, port); } catch { if (_clientSocket != null) { _clientSocket.Close(); } throw; } if (NetEventSource.Log.IsEnabled()) { NetEventSource.Exit(NetEventSource.ComponentType.Socket, this, nameof(TcpClient), null); } }
// This creates a TcpListener that listens on both IPv4 and IPv6 on the given port. public static TcpListener Create(int port) { if (Logging.On) { Logging.Enter(Logging.Sockets, "TcpListener.Create", "Port: " + port); } if (!TcpValidationHelpers.ValidatePortNumber(port)) { throw new ArgumentOutOfRangeException("port"); } TcpListener listener = new TcpListener(IPAddress.IPv6Any, port); listener.Server.DualMode = true; if (Logging.On) { Logging.Exit(Logging.Sockets, "TcpListener.Create", "Port: " + port); } return(listener); }
// Establishes a connection with the host at the specified address on the // specified port. public void Connect(IPAddress addr, int port) { // Validate input parameters. if (_cleanedUp) { throw new ObjectDisposedException(this.GetType().FullName); } if (addr == null) { throw new ArgumentNullException("addr"); } if (!TcpValidationHelpers.ValidatePortNumber(port)) { throw new ArgumentOutOfRangeException("port"); } // IPv6 Changes: Removed redundant call to CheckForBroadcast() since // it is made in the real Connect() method. IPEndPoint endPoint = new IPEndPoint(addr, port); Connect(endPoint); }
// Initializes a new instance of the TcpListener class that listens to the specified IP address // and port. public TcpListener(IPAddress localaddr, int port) { if (NetEventSource.Log.IsEnabled()) { NetEventSource.Enter(NetEventSource.ComponentType.Socket, this, "TcpListener", localaddr); } if (localaddr == null) { throw new ArgumentNullException(nameof(localaddr)); } if (!TcpValidationHelpers.ValidatePortNumber(port)) { throw new ArgumentOutOfRangeException(nameof(port)); } _serverSocketEP = new IPEndPoint(localaddr, port); _serverSocket = new Socket(_serverSocketEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp); if (NetEventSource.Log.IsEnabled()) { NetEventSource.Exit(NetEventSource.ComponentType.Socket, this, "TcpListener", null); } }
// Initializes a new instance of the TcpListener class that listens to the specified IP address // and port. public TcpListener(IPAddress localaddr, int port) { if (Logging.On) { Logging.Enter(Logging.Sockets, this, "TcpListener", localaddr); } if (localaddr == null) { throw new ArgumentNullException("localaddr"); } if (!TcpValidationHelpers.ValidatePortNumber(port)) { throw new ArgumentOutOfRangeException("port"); } _serverSocketEP = new IPEndPoint(localaddr, port); _serverSocket = new Socket(_serverSocketEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp); if (Logging.On) { Logging.Exit(Logging.Sockets, this, "TcpListener", null); } }
// This creates a TcpListener that listens on both IPv4 and IPv6 on the given port. public static TcpListener Create(int port) { if (NetEventSource.IsEnabled) { NetEventSource.Enter(null, port); } if (!TcpValidationHelpers.ValidatePortNumber(port)) { throw new ArgumentOutOfRangeException(nameof(port)); } TcpListener listener = new TcpListener(IPAddress.IPv6Any, port); listener.Server.DualMode = true; if (NetEventSource.IsEnabled) { NetEventSource.Exit(null, port); } return(listener); }
// This creates a TcpListener that listens on both IPv4 and IPv6 on the given port. public static TcpListener Create(int port) { if (NetEventSource.Log.IsEnabled()) { NetEventSource.Enter(NetEventSource.ComponentType.Socket, "TcpListener.Create", "Port: " + port, null); } if (!TcpValidationHelpers.ValidatePortNumber(port)) { throw new ArgumentOutOfRangeException(nameof(port)); } TcpListener listener = new TcpListener(IPAddress.IPv6Any, port); listener.Server.DualMode = true; if (NetEventSource.Log.IsEnabled()) { NetEventSource.Exit(NetEventSource.ComponentType.Socket, "TcpListener.Create", "Port: " + port, null); } return(listener); }
// Connects the Client to the specified port on the specified host. public void Connect(string hostname, int port) { if (NetEventSource.Log.IsEnabled()) { NetEventSource.Enter(NetEventSource.ComponentType.Socket, this, nameof(Connect), hostname); } if (_cleanedUp) { throw new ObjectDisposedException(this.GetType().FullName); } if (hostname == null) { throw new ArgumentNullException(nameof(hostname)); } if (!TcpValidationHelpers.ValidatePortNumber(port)) { throw new ArgumentOutOfRangeException(nameof(port)); } // Check for already connected and throw here. This check // is not required in the other connect methods as they // will throw from WinSock. Here, the situation is more // complex since we have to resolve a hostname so it's // easier to simply block the request up front. if (_active) { throw new SocketException((int)SocketError.IsConnected); } ConnectCore(hostname, port); if (NetEventSource.Log.IsEnabled()) { NetEventSource.Exit(NetEventSource.ComponentType.Socket, this, nameof(Connect), null); } }
public void Connect(string hostname, int port) { ThrowIfDisposed(); if (hostname == null) { throw new ArgumentNullException(nameof(hostname)); } if (!TcpValidationHelpers.ValidatePortNumber(port)) { throw new ArgumentOutOfRangeException(nameof(port)); } // We must now look for addresses that use a compatible address family to the client socket. However, in the // case of the <hostname,port> constructor we will have deferred creating the socket and will do that here // instead. IPAddress[] addresses = Dns.GetHostAddresses(hostname); Exception lastex = null; Socket ipv6Socket = null; Socket ipv4Socket = null; try { if (_clientSocket == null) { if (Socket.OSSupportsIPv4) { ipv4Socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); } if (Socket.OSSupportsIPv6) { ipv6Socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Dgram, ProtocolType.Udp); } } foreach (IPAddress address in addresses) { try { if (_clientSocket == null) { // We came via the <hostname,port> constructor. Set the // address family appropriately, create the socket and // try to connect. if (address.AddressFamily == AddressFamily.InterNetwork && ipv4Socket != null) { ipv4Socket.Connect(address, port); _clientSocket = ipv4Socket; if (ipv6Socket != null) { ipv6Socket.Close(); } } else if (ipv6Socket != null) { ipv6Socket.Connect(address, port); _clientSocket = ipv6Socket; if (ipv4Socket != null) { ipv4Socket.Close(); } } _family = address.AddressFamily; _active = true; break; } else if (IsAddressFamilyCompatible(address.AddressFamily)) { // Only use addresses with a matching family Connect(new IPEndPoint(address, port)); _active = true; break; } } catch (Exception ex) { if (ExceptionCheck.IsFatal(ex)) { throw; } lastex = ex; } } } catch (Exception ex) { if (ExceptionCheck.IsFatal(ex)) { throw; } lastex = ex; } finally { //cleanup temp sockets if failed //main socket gets closed when tcpclient gets closed //did we connect? if (!_active) { if (ipv6Socket != null) { ipv6Socket.Close(); } if (ipv4Socket != null) { ipv4Socket.Close(); } // The connect failed - rethrow the last error we had if (lastex != null) { throw lastex; } else { throw new SocketException((int)SocketError.NotConnected); } } } }
// Connects the Client to the specified port on the specified host. public void Connect(string hostname, int port) { if (Logging.On) { Logging.Enter(Logging.Sockets, this, "Connect", hostname); } if (_cleanedUp) { throw new ObjectDisposedException(this.GetType().FullName); } if (hostname == null) { throw new ArgumentNullException("hostname"); } if (!TcpValidationHelpers.ValidatePortNumber(port)) { throw new ArgumentOutOfRangeException("port"); } // Check for already connected and throw here. This check // is not required in the other connect methods as they // will throw from WinSock. Here, the situation is more // complex since we have to resolve a hostname so it's // easier to simply block the request up front. if (_active) { throw new SocketException((int)SocketError.IsConnected); } // IPv6: We need to process each of the addresses return from // DNS when trying to connect. Use of AddressList[0] is // bad form. IPAddress[] addresses = Dns.GetHostAddressesAsync(hostname).GetAwaiter().GetResult(); Exception lastex = null; Socket ipv6Socket = null; Socket ipv4Socket = null; try { if (_clientSocket == null) { if (Socket.OSSupportsIPv4) { ipv4Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); } if (Socket.OSSupportsIPv6) { ipv6Socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp); } } foreach (IPAddress address in addresses) { try { if (_clientSocket == null) { // We came via the <hostname,port> constructor. Set the // address family appropriately, create the socket and // try to connect. if (address.AddressFamily == AddressFamily.InterNetwork && ipv4Socket != null) { ipv4Socket.Connect(address, port); _clientSocket = ipv4Socket; if (ipv6Socket != null) { ipv6Socket.Dispose(); } } else if (ipv6Socket != null) { ipv6Socket.Connect(address, port); _clientSocket = ipv6Socket; if (ipv4Socket != null) { ipv4Socket.Dispose(); } } _family = address.AddressFamily; _active = true; break; } else if (address.AddressFamily == _family) { // Only use addresses with a matching family. Connect(new IPEndPoint(address, port)); _active = true; break; } } catch (Exception ex) { if (ex is OutOfMemoryException) { throw; } lastex = ex; } } } catch (Exception ex) { if (ex is OutOfMemoryException) { throw; } lastex = ex; } finally { // Cleanup temp sockets if failed. Main socket gets closed when TCPClient gets closed. // Did we connect? if (!_active) { if (ipv6Socket != null) { ipv6Socket.Dispose(); } if (ipv4Socket != null) { ipv4Socket.Dispose(); } // The connect failed - rethrow the last error we had. if (lastex != null) { throw lastex; } else { throw new SocketException((int)SocketError.NotConnected); } } } if (Logging.On) { Logging.Exit(Logging.Sockets, this, "Connect", null); } }
// Connects the Client to the specified port on the specified host. public void Connect(string hostname, int port) { if (NetEventSource.IsEnabled) { NetEventSource.Enter(this, hostname); } if (_cleanedUp) { throw new ObjectDisposedException(GetType().FullName); } if (hostname == null) { throw new ArgumentNullException(nameof(hostname)); } if (!TcpValidationHelpers.ValidatePortNumber(port)) { throw new ArgumentOutOfRangeException(nameof(port)); } // Check for already connected and throw here. This check // is not required in the other connect methods as they // will throw from WinSock. Here, the situation is more // complex since we have to resolve a hostname so it's // easier to simply block the request up front. if (_active) { throw new SocketException((int)SocketError.IsConnected); } // IPv6: We need to process each of the addresses returned from // DNS when trying to connect. Use of AddressList[0] is // bad form. IPAddress[] addresses = Dns.GetHostAddresses(hostname); ExceptionDispatchInfo lastex = null; try { foreach (IPAddress address in addresses) { Socket tmpSocket = null; try { if (_clientSocket == null) { // We came via the <hostname,port> constructor. Set the address family appropriately, // create the socket and try to connect. Debug.Assert(address.AddressFamily == AddressFamily.InterNetwork || address.AddressFamily == AddressFamily.InterNetworkV6); if ((address.AddressFamily == AddressFamily.InterNetwork && Socket.OSSupportsIPv4) || Socket.OSSupportsIPv6) { tmpSocket = new Socket(address.AddressFamily, SocketType.Stream, ProtocolType.Tcp); tmpSocket.Connect(address, port); _clientSocket = tmpSocket; tmpSocket = null; } _family = address.AddressFamily; _active = true; break; } else if (address.AddressFamily == _family || _family == AddressFamily.Unknown) { // Only use addresses with a matching family Connect(new IPEndPoint(address, port)); _active = true; break; } } catch (Exception ex) when(!(ex is OutOfMemoryException)) { if (tmpSocket != null) { tmpSocket.Dispose(); tmpSocket = null; } lastex = ExceptionDispatchInfo.Capture(ex); } } } finally { if (!_active) { // The connect failed - rethrow the last error we had lastex?.Throw(); throw new SocketException((int)SocketError.NotConnected); } } if (NetEventSource.IsEnabled) { NetEventSource.Exit(this); } }
// Establishes a connection to the specified port on the specified host. public void Connect(string hostname, int port) { // Validate input parameters. if (_cleanedUp) { throw new ObjectDisposedException(this.GetType().FullName); } if (hostname == null) { throw new ArgumentNullException("hostname"); } if (!TcpValidationHelpers.ValidatePortNumber(port)) { throw new ArgumentOutOfRangeException("port"); } // IPv6 Changes: instead of just using the first address in the list, // we must now look for addresses that use a compatible // address family to the client socket. // However, in the case of the <hostname,port> constructor // we will have deferred creating the socket and will // do that here instead. // In addition, the redundant CheckForBroadcast call was // removed here since it is called from Connect(). IPAddress[] addresses = Dns.GetHostAddressesAsync(hostname).GetAwaiter().GetResult(); Exception lastex = null; Socket ipv6Socket = null; Socket ipv4Socket = null; try { if (_clientSocket == null) { if (Socket.OSSupportsIPv4) { ipv4Socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); } if (Socket.OSSupportsIPv6) { ipv6Socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Dgram, ProtocolType.Udp); } } foreach (IPAddress address in addresses) { try { if (_clientSocket == null) { // We came via the <hostname,port> constructor. Set the // address family appropriately, create the socket and // try to connect. if (address.AddressFamily == AddressFamily.InterNetwork && ipv4Socket != null) { ipv4Socket.Connect(address, port); _clientSocket = ipv4Socket; if (ipv6Socket != null) { ipv6Socket.Dispose(); } } else if (ipv6Socket != null) { ipv6Socket.Connect(address, port); _clientSocket = ipv6Socket; if (ipv4Socket != null) { ipv4Socket.Dispose(); } } _family = address.AddressFamily; _active = true; break; } else if (address.AddressFamily == _family) { // Only use addresses with a matching family. Connect(new IPEndPoint(address, port)); _active = true; break; } } catch (Exception ex) { if (ExceptionCheck.IsFatal(ex)) { throw; } lastex = ex; } } } catch (Exception ex) { if (ExceptionCheck.IsFatal(ex)) { throw; } lastex = ex; } finally { // Cleanup temp sockets on failure. The main socket gets closed when the UDPClient // gets closed. // Did we connect? if (!_active) { if (ipv6Socket != null) { ipv6Socket.Dispose(); } if (ipv4Socket != null) { ipv4Socket.Dispose(); } // The connect failed - rethrow the last error we had. if (lastex != null) { throw lastex; } else { throw new SocketException((int)SocketError.NotConnected); } } } }
// Connects the Client to the specified port on the specified host. public void Connect(string hostname, int port) { ThrowIfDisposed(); ArgumentNullException.ThrowIfNull(hostname); if (!TcpValidationHelpers.ValidatePortNumber(port)) { throw new ArgumentOutOfRangeException(nameof(port)); } // Check for already connected and throw here. This check // is not required in the other connect methods as they // will throw from WinSock. Here, the situation is more // complex since we have to resolve a hostname so it's // easier to simply block the request up front. if (_active) { throw new SocketException((int)SocketError.IsConnected); } // IPv6: We need to process each of the addresses returned from // DNS when trying to connect. Use of AddressList[0] is // bad form. IPAddress[] addresses = Dns.GetHostAddresses(hostname); ExceptionDispatchInfo?lastex = null; try { foreach (IPAddress address in addresses) { try { if (_clientSocket == null) { // We came via the <hostname,port> constructor. Set the address family appropriately, // create the socket and try to connect. Debug.Assert(address.AddressFamily == AddressFamily.InterNetwork || address.AddressFamily == AddressFamily.InterNetworkV6); if ((address.AddressFamily == AddressFamily.InterNetwork && Socket.OSSupportsIPv4) || Socket.OSSupportsIPv6) { var socket = new Socket(address.AddressFamily, SocketType.Stream, ProtocolType.Tcp); if (address.IsIPv4MappedToIPv6) { socket.DualMode = true; } // Use of Interlocked.Exchanged ensures _clientSocket is written before Disposed is read. Interlocked.Exchange(ref _clientSocket !, socket); if (Disposed) { // Dispose the socket so it throws ObjectDisposedException when we Connect. socket.Dispose(); } try { socket.Connect(address, port); } catch { _clientSocket = null !; throw; } } _family = address.AddressFamily; _active = true; break; } else if (address.AddressFamily == _family || _family == AddressFamily.Unknown) { // Only use addresses with a matching family Connect(new IPEndPoint(address, port)); _active = true; break; } } catch (Exception ex) when(!(ex is OutOfMemoryException)) { lastex = ExceptionDispatchInfo.Capture(ex); } } } finally { if (!_active) { // The connect failed - rethrow the last error we had lastex?.Throw(); throw new SocketException((int)SocketError.NotConnected); } } }