@@ -44,16 +44,20 @@ public PooledSocket(DnsEndPoint endpoint, TimeSpan connectionTimeout, TimeSpan r
4444 socket . ReceiveTimeout = rcv ;
4545 socket . SendTimeout = rcv ;
4646
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+ }
4851
4952 this . socket = socket ;
5053 this . endpoint = endpoint ;
5154
5255 this . inputStream = new NetworkStream ( socket ) ;
5356 }
5457
55- private void ConnectWithTimeout ( Socket socket , DnsEndPoint endpoint , int timeout )
58+ private bool ConnectWithTimeout ( Socket socket , DnsEndPoint endpoint , int timeout )
5659 {
60+ bool connected = false ;
5761 socket . SetSocketOption ( SocketOptionLevel . Socket , SocketOptionName . KeepAlive , true ) ;
5862 var args = new SocketAsyncEventArgs ( ) ;
5963
@@ -64,25 +68,31 @@ private void ConnectWithTimeout(Socket socket, DnsEndPoint endpoint, int timeout
6468 . FirstOrDefault ( ip => ip . AddressFamily == AddressFamily . InterNetwork ) ;
6569 if ( address == null )
6670 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 ) ;
7371 }
7472
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 ( )
7677 {
77- args . Completed += ( s , e ) => mres . Set ( ) ;
78- if ( socket . ConnectAsync ( args ) )
78+ if ( ! socket . Connected )
7979 {
80- if ( ! mres . Wait ( timeout ) )
81- {
82- throw new TimeoutException ( "Could not connect to " + endpoint ) ;
83- }
80+ socket . Dispose ( ) ;
8481 }
8582 }
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 ;
8696 }
8797
8898 public Action < PooledSocket > CleanupCallback { get ; set ; }
0 commit comments