Skip to content

Commit 3f6accb

Browse files
committed
Add a loop to SocketAbstraction.ReadAsync
In order to ensure the buffer is read completely, as in SocketAbstraction.Read
1 parent 75ced08 commit 3f6accb

File tree

3 files changed

+28
-24
lines changed

3 files changed

+28
-24
lines changed

src/Renci.SshNet/Abstractions/SocketAbstraction.Async.cs

Lines changed: 0 additions & 17 deletions
This file was deleted.

src/Renci.SshNet/Abstractions/SocketAbstraction.cs

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@
33
using System.Net;
44
using System.Net.Sockets;
55
using System.Threading;
6-
#if NET6_0_OR_GREATER == false
76
using System.Threading.Tasks;
8-
#endif
97

108
using Renci.SshNet.Common;
119

@@ -151,11 +149,34 @@ public static int Read(Socket socket, byte[] buffer, int offset, int size, TimeS
151149
return totalBytesRead;
152150
}
153151

154-
#if NET6_0_OR_GREATER == false
155-
public static ValueTask<int> ReadAsync(Socket socket, byte[] buffer, CancellationToken cancellationToken)
152+
public static async ValueTask<int> ReadAsync(Socket socket, byte[] buffer, int offset, int size, CancellationToken cancellationToken)
156153
{
157-
return socket.ReceiveAsync(new ArraySegment<byte>(buffer, 0, buffer.Length), SocketFlags.None, cancellationToken);
154+
var totalBytesRead = 0;
155+
var totalBytesToRead = size;
156+
157+
do
158+
{
159+
try
160+
{
161+
var bytesRead = await socket.ReceiveAsync(new ArraySegment<byte>(buffer, offset + totalBytesRead, totalBytesToRead - totalBytesRead), SocketFlags.None, cancellationToken).ConfigureAwait(false);
162+
if (bytesRead == 0)
163+
{
164+
return 0;
165+
}
166+
167+
totalBytesRead += bytesRead;
168+
}
169+
catch (SocketException ex) when (ex.SocketErrorCode == SocketError.TimedOut)
170+
{
171+
throw new SshOperationTimeoutException(string.Format(CultureInfo.InvariantCulture,
172+
"Socket read operation has timed out after {0:F0} milliseconds.",
173+
socket.ReceiveTimeout),
174+
ex);
175+
}
176+
}
177+
while (totalBytesRead < totalBytesToRead);
178+
179+
return totalBytesRead;
158180
}
159-
#endif
160181
}
161182
}

src/Renci.SshNet/Connection/ProtocolVersionExchange.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ private static async Task<string> SocketReadLineAsync(Socket socket, List<byte>
187187
// to be processed by subsequent invocations.
188188
while (true)
189189
{
190-
var bytesRead = await SocketAbstraction.ReadAsync(socket, data, cancellationToken).ConfigureAwait(false);
190+
var bytesRead = await SocketAbstraction.ReadAsync(socket, data, 0, data.Length, cancellationToken).ConfigureAwait(false);
191191
if (bytesRead == 0)
192192
{
193193
throw new SshConnectionException("The connection was closed by the remote host.");

0 commit comments

Comments
 (0)