Skip to content

Commit e0b32a4

Browse files
committed
Add Connect overload that takes existing Socket instance.
1 parent de06f12 commit e0b32a4

File tree

1 file changed

+31
-14
lines changed

1 file changed

+31
-14
lines changed

src/Renci.SshNet/Abstractions/SocketAbstraction.cs

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)