@@ -49,8 +49,18 @@ public static bool CanWrite(Socket socket)
4949
5050 public static Socket Connect ( IPEndPoint remoteEndpoint , TimeSpan connectTimeout )
5151 {
52- var socket = new Socket ( remoteEndpoint . AddressFamily , SocketType . Stream , ProtocolType . Tcp ) { NoDelay = true } ;
52+ var socket = new Socket ( remoteEndpoint . AddressFamily , SocketType . Stream , ProtocolType . Tcp ) { NoDelay = true } ;
53+ ConnectCore ( socket , remoteEndpoint , connectTimeout , true ) ;
54+ return socket ;
55+ }
56+
57+ public static void Connect ( Socket socket , IPEndPoint remoteEndpoint , TimeSpan connectTimeout )
58+ {
59+ ConnectCore ( socket , remoteEndpoint , connectTimeout , false ) ;
60+ }
5361
62+ private static void ConnectCore ( Socket socket , IPEndPoint remoteEndpoint , TimeSpan connectTimeout , bool ownsSocket )
63+ {
5464#if FEATURE_SOCKET_EAP
5565 var connectCompleted = new ManualResetEvent ( false ) ;
5666 var args = new SocketAsyncEventArgs
@@ -66,8 +76,11 @@ public static Socket Connect(IPEndPoint remoteEndpoint, TimeSpan connectTimeout)
6676 {
6777 // avoid ObjectDisposedException in ConnectCompleted
6878 args . Completed -= ConnectCompleted ;
69- // dispose Socket
70- socket . Dispose ( ) ;
79+ if ( ownsSocket )
80+ {
81+ // dispose Socket
82+ socket . Dispose ( ) ;
83+ }
7184 // dispose ManualResetEvent
7285 connectCompleted . Dispose ( ) ;
7386 // dispose SocketAsyncEventArgs
@@ -86,8 +99,12 @@ public static Socket Connect(IPEndPoint remoteEndpoint, TimeSpan connectTimeout)
8699 {
87100 var socketError = ( int ) args . SocketError ;
88101
89- // dispose Socket
90- socket . Dispose ( ) ;
102+ if ( ownsSocket )
103+ {
104+ // dispose Socket
105+ socket . Dispose ( ) ;
106+ }
107+
91108 // dispose SocketAsyncEventArgs
92109 args . Dispose ( ) ;
93110
@@ -96,20 +113,16 @@ public static Socket Connect(IPEndPoint remoteEndpoint, TimeSpan connectTimeout)
96113
97114 // dispose SocketAsyncEventArgs
98115 args . Dispose ( ) ;
99-
100- return socket ;
101116#elif FEATURE_SOCKET_APM
102117 var connectResult = socket . BeginConnect ( remoteEndpoint , null , null ) ;
103118 if ( ! connectResult . AsyncWaitHandle . WaitOne ( connectTimeout , false ) )
104119 throw new SshOperationTimeoutException ( string . Format ( CultureInfo . InvariantCulture ,
105120 "Connection failed to establish within {0:F0} milliseconds." , connectTimeout . TotalMilliseconds ) ) ;
106121 socket . EndConnect ( connectResult ) ;
107- return socket ;
108122#elif FEATURE_SOCKET_TAP
109123 if ( ! socket . ConnectAsync ( remoteEndpoint ) . Wait ( connectTimeout ) )
110124 throw new SshOperationTimeoutException ( string . Format ( CultureInfo . InvariantCulture ,
111125 "Connection failed to establish within {0:F0} milliseconds." , connectTimeout . TotalMilliseconds ) ) ;
112- return socket ;
113126#else
114127 #error Connecting to a remote endpoint is not implemented.
115128#endif
@@ -311,24 +324,28 @@ public static byte[] Read(Socket socket, int size, TimeSpan timeout)
311324 /// <param name="buffer">An array of type <see cref="byte"/> that is the storage location for the received data. </param>
312325 /// <param name="offset">The position in <paramref name="buffer"/> parameter to store the received data.</param>
313326 /// <param name="size">The number of bytes to receive.</param>
314- /// <param name="timeout">Specifies the amount of time after which the call will time out .</param>
327+ /// <param name="readTimeout">The maximum time to wait until <paramref name="size"/> bytes have been received .</param>
315328 /// <returns>
316329 /// The number of bytes received.
317330 /// </returns>
318331 /// <remarks>
332+ /// <para>
319333 /// If no data is available for reading, the <see cref="Read(Socket, byte[], int, int, TimeSpan)"/> method will
320334 /// block until data is available or the time-out value is exceeded. If the time-out value is exceeded, the
321335 /// <see cref="Read(Socket, byte[], int, int, TimeSpan)"/> call will throw a <see cref="SshOperationTimeoutException"/>.
322- /// If you are in non-blocking mode, and there is no data available in the in the protocol stack buffer, the
336+ /// </para>
337+ /// <para>
338+ /// If you are in non-blocking mode, and there is no data available in the in the protocol stack buffer, the
323339 /// <see cref="Read(Socket, byte[], int, int, TimeSpan)"/> method will complete immediately and throw a <see cref="SocketException"/>.
340+ /// </para>
324341 /// </remarks>
325- public static int Read ( Socket socket , byte [ ] buffer , int offset , int size , TimeSpan timeout )
342+ public static int Read ( Socket socket , byte [ ] buffer , int offset , int size , TimeSpan readTimeout )
326343 {
327344#if FEATURE_SOCKET_SYNC
328345 var totalBytesRead = 0 ;
329346 var totalBytesToRead = size ;
330347
331- socket . ReceiveTimeout = ( int ) timeout . TotalMilliseconds ;
348+ socket . ReceiveTimeout = ( int ) readTimeout . TotalMilliseconds ;
332349
333350 do
334351 {
@@ -350,7 +367,7 @@ public static int Read(Socket socket, byte[] buffer, int offset, int size, TimeS
350367
351368 if ( ex . SocketErrorCode == SocketError . TimedOut )
352369 throw new SshOperationTimeoutException ( string . Format ( CultureInfo . InvariantCulture ,
353- "Socket read operation has timed out after {0:F0} milliseconds." , timeout . TotalMilliseconds ) ) ;
370+ "Socket read operation has timed out after {0:F0} milliseconds." , readTimeout . TotalMilliseconds ) ) ;
354371
355372 throw ;
356373 }
0 commit comments