From 3cad131b4d731cefe9de9e6bf1ca699f7cdc248f Mon Sep 17 00:00:00 2001 From: Tomas Weinfurt Date: Tue, 12 Apr 2022 23:32:55 -0700 Subject: [PATCH] remove duplicate Connect logic from TcpClient --- .../src/System/Net/Sockets/TCPClient.cs | 87 +------------------ 1 file changed, 4 insertions(+), 83 deletions(-) diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/TCPClient.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/TCPClient.cs index 576b44bc67339d..499e5d7d7122a8 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/TCPClient.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/TCPClient.cs @@ -55,7 +55,7 @@ public TcpClient(IPEndPoint localEP!!) // 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) + public TcpClient(string hostname!!, int port) : this(AddressFamily.Unknown) { if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, hostname); if (!TcpValidationHelpers.ValidatePortNumber(port)) @@ -63,8 +63,6 @@ public TcpClient(string hostname!!, int port) throw new ArgumentOutOfRangeException(nameof(port)); } - _family = AddressFamily.Unknown; - try { Connect(hostname, port); @@ -128,87 +126,10 @@ public void Connect(string hostname, int 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 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; - } - } + Client.Connect(hostname, port); + _family = Client.AddressFamily; + _active = true; - _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); - } - } } // Connects the Client to the specified port on the specified host.