diff --git a/src/System.Net.Sockets/src/Resources/Strings.resx b/src/System.Net.Sockets/src/Resources/Strings.resx
index 328f67c37120..37c5e994715a 100644
--- a/src/System.Net.Sockets/src/Resources/Strings.resx
+++ b/src/System.Net.Sockets/src/Resources/Strings.resx
@@ -273,4 +273,7 @@
Argument must be between {0} and {1}.
+
+ Sockets on this platform are invalid for use after a failed connection attempt, and as a result do not support attempts to connect to multiple endpoints. Use the static Connect methods or the instance Connect methods that take a single, non-DNS endpoint.
+
\ No newline at end of file
diff --git a/src/System.Net.Sockets/src/System/Net/Sockets/Socket.cs b/src/System.Net.Sockets/src/System/Net/Sockets/Socket.cs
index 4744c05e36cf..a5e0ff0aac6c 100644
--- a/src/System.Net.Sockets/src/System/Net/Sockets/Socket.cs
+++ b/src/System.Net.Sockets/src/System/Net/Sockets/Socket.cs
@@ -980,77 +980,18 @@ public void Connect(IPAddress[] addresses, int port)
{
throw new NotSupportedException(SR.net_invalidversion);
}
+ ThrowIfNotSupportsMultipleConnectAttempts();
- // Disable CS0162: Unreachable code detected
- //
- // SuportsMultipleConnectAttempts is a constant; when false, the following lines will trigger CS0162.
-#pragma warning disable 162
Exception lastex = null;
- if (SocketPal.SupportsMultipleConnectAttempts)
+ foreach (IPAddress address in addresses)
{
- foreach (IPAddress address in addresses)
- {
- if (CanTryAddressFamily(address.AddressFamily))
- {
- try
- {
- Connect(new IPEndPoint(address, port));
- lastex = null;
- break;
- }
- catch (Exception ex)
- {
- if (ExceptionCheck.IsFatal(ex))
- {
- throw;
- }
- lastex = ex;
- }
- }
- }
- }
- else
- {
- EndPoint endpoint = null;
- foreach (IPAddress address in addresses)
- {
- if (CanTryAddressFamily(address.AddressFamily))
- {
- Socket attemptSocket = null;
- try
- {
- attemptSocket = new Socket(_addressFamily, _socketType, _protocolType);
- if (IsDualMode)
- {
- attemptSocket.DualMode = true;
- }
-
- var attemptEndpoint = new IPEndPoint(address, port);
- attemptSocket.Connect(attemptEndpoint);
- endpoint = attemptEndpoint;
- lastex = null;
- break;
- }
- catch (Exception ex)
- {
- lastex = ex;
- }
- finally
- {
- if (attemptSocket != null)
- {
- attemptSocket.Dispose();
- }
- }
- }
- }
-
- if (endpoint != null)
+ if (CanTryAddressFamily(address.AddressFamily))
{
try
{
- Connect(endpoint);
+ Connect(new IPEndPoint(address, port));
lastex = null;
+ break;
}
catch (Exception ex)
{
@@ -1062,7 +1003,6 @@ public void Connect(IPAddress[] addresses, int port)
}
}
}
-#pragma warning restore
if (lastex != null)
{
@@ -2415,6 +2355,8 @@ internal IAsyncResult BeginConnect(string host, int port, AsyncCallback requestC
throw new InvalidOperationException(SR.net_sockets_mustnotlisten);
}
+ ThrowIfNotSupportsMultipleConnectAttempts();
+
// Here, want to flow the context. No need to lock.
MultipleAddressConnectAsyncResult result = new MultipleAddressConnectAsyncResult(null, port, this, state, requestCallback);
result.StartPostingAsyncOp(false);
@@ -2438,6 +2380,14 @@ internal IAsyncResult BeginConnect(string host, int port, AsyncCallback requestC
return result;
}
+ private static void ThrowIfNotSupportsMultipleConnectAttempts()
+ {
+ if (!SocketPal.SupportsMultipleConnectAttempts)
+ {
+ throw new PlatformNotSupportedException(SR.net_sockets_connect_multiaddress_notsupported);
+ }
+ }
+
internal IAsyncResult BeginConnect(IPAddress address, int port, AsyncCallback requestCallback, object state)
{
if (s_loggingEnabled)
@@ -2502,6 +2452,7 @@ internal IAsyncResult BeginConnect(IPAddress[] addresses, int port, AsyncCallbac
{
throw new InvalidOperationException(SR.net_sockets_mustnotlisten);
}
+ ThrowIfNotSupportsMultipleConnectAttempts();
// Set up the result to capture the context. No need for a lock.
MultipleAddressConnectAsyncResult result = new MultipleAddressConnectAsyncResult(addresses, port, this, state, requestCallback);
@@ -4408,6 +4359,8 @@ public bool ConnectAsync(SocketAsyncEventArgs e)
throw new NotSupportedException(SR.net_invalidversion);
}
+ ThrowIfNotSupportsMultipleConnectAttempts();
+
MultipleConnectAsync multipleConnectAsync = new SingleSocketMultipleConnectAsync(this, true);
e.StartOperationCommon(this);
@@ -4518,6 +4471,10 @@ public static bool ConnectAsync(SocketType socketType, ProtocolType protocolType
// Disable CS0162 and CS0429: Unreachable code detected
//
// SuportsMultipleConnectAttempts is a constant; when false, the following lines will trigger CS0162 or CS0429.
+ //
+ // This is the only *Connect* API that actually supports multiple endpoint attempts, as it's responsible
+ // for creating each Socket instance and can create one per attempt (with the instance methods, once a
+ // connect fails, on unix systems that socket can't be used for subsequent connect attempts).
#pragma warning disable 162, 429
multipleConnectAsync = SocketPal.SupportsMultipleConnectAttempts ?
(MultipleConnectAsync)(new DualSocketMultipleConnectAsync(socketType, protocolType)) :