@@ -44,16 +44,20 @@ public PooledSocket(DnsEndPoint endpoint, TimeSpan connectionTimeout, TimeSpan r
44
44
socket . ReceiveTimeout = rcv ;
45
45
socket . SendTimeout = rcv ;
46
46
47
- ConnectWithTimeout ( socket , endpoint , timeout ) ;
47
+ if ( ! ConnectWithTimeout ( socket , endpoint , timeout ) )
48
+ {
49
+ throw new TimeoutException ( $ "Could not connect to { endpoint . Host } :{ endpoint . Port } .") ;
50
+ }
48
51
49
52
this . socket = socket ;
50
53
this . endpoint = endpoint ;
51
54
52
55
this . inputStream = new NetworkStream ( socket ) ;
53
56
}
54
57
55
- private void ConnectWithTimeout ( Socket socket , DnsEndPoint endpoint , int timeout )
58
+ private bool ConnectWithTimeout ( Socket socket , DnsEndPoint endpoint , int timeout )
56
59
{
60
+ bool connected = false ;
57
61
socket . SetSocketOption ( SocketOptionLevel . Socket , SocketOptionName . KeepAlive , true ) ;
58
62
var args = new SocketAsyncEventArgs ( ) ;
59
63
@@ -64,25 +68,31 @@ private void ConnectWithTimeout(Socket socket, DnsEndPoint endpoint, int timeout
64
68
. FirstOrDefault ( ip => ip . AddressFamily == AddressFamily . InterNetwork ) ;
65
69
if ( address == null )
66
70
throw new ArgumentException ( String . Format ( "Could not resolve host '{0}'." , endpoint . Host ) ) ;
67
- args . RemoteEndPoint = new IPEndPoint ( address , endpoint . Port ) ;
68
- }
69
- else
70
- {
71
- //DnsEndPoint is not working on linux
72
- args . RemoteEndPoint = new IPEndPoint ( address , endpoint . Port ) ;
73
71
}
74
72
75
- using ( var mres = new ManualResetEventSlim ( ) )
73
+ //Learn from https://github.com/dotnet/corefx/blob/release/2.2/src/System.Data.SqlClient/src/System/Data/SqlClient/SNI/SNITcpHandle.cs#L180
74
+ var cts = new CancellationTokenSource ( ) ;
75
+ cts . CancelAfter ( timeout ) ;
76
+ void Cancel ( )
76
77
{
77
- args . Completed += ( s , e ) => mres . Set ( ) ;
78
- if ( socket . ConnectAsync ( args ) )
78
+ if ( ! socket . Connected )
79
79
{
80
- if ( ! mres . Wait ( timeout ) )
81
- {
82
- throw new TimeoutException ( "Could not connect to " + endpoint ) ;
83
- }
80
+ socket . Dispose ( ) ;
84
81
}
85
82
}
83
+ cts . Token . Register ( Cancel ) ;
84
+
85
+ socket . Connect ( address , endpoint . Port ) ;
86
+ if ( socket . Connected )
87
+ {
88
+ connected = true ;
89
+ }
90
+ else
91
+ {
92
+ socket . Dispose ( ) ;
93
+ }
94
+
95
+ return connected ;
86
96
}
87
97
88
98
public Action < PooledSocket > CleanupCallback { get ; set ; }
0 commit comments