Skip to content

Commit

Permalink
make SocketAddress useable after receive timeout (dotnet#102142)
Browse files Browse the repository at this point in the history
* make SocketAddress useable after receive timeout

* Update src/libraries/System.Net.Sockets/tests/FunctionalTests/SendReceive/SendReceiveMisc.cs

Co-authored-by: Stephen Toub <stoub@microsoft.com>

---------

Co-authored-by: Stephen Toub <stoub@microsoft.com>
  • Loading branch information
wfurt and stephentoub authored May 16, 2024
1 parent ffad857 commit ffa1bea
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1909,8 +1909,6 @@ public int ReceiveFrom(Span<byte> buffer, SocketFlags socketFlags, SocketAddress

int bytesTransferred;
SocketError errorCode = SocketPal.ReceiveFrom(_handle, buffer, socketFlags, receivedAddress.Buffer, out int socketAddressSize, out bytesTransferred);
receivedAddress.Size = socketAddressSize;

UpdateReceiveSocketErrorForDisposed(ref errorCode, bytesTransferred);
// If the native call fails we'll throw a SocketException.
if (errorCode != SocketError.Success)
Expand All @@ -1927,6 +1925,7 @@ public int ReceiveFrom(Span<byte> buffer, SocketFlags socketFlags, SocketAddress
if (SocketType == SocketType.Dgram) SocketsTelemetry.Log.DatagramReceived();
}

receivedAddress.Size = socketAddressSize;
return bytesTransferred;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -283,5 +283,41 @@ public async Task Socket_ReceiveFlags_Success()
Assert.Equal(0, receiver.Available);
}
}

[Theory]
[InlineData(true)]
[InlineData(false)]
public void ReceiveFrom_MultipleRounds_Success(bool async)
{
using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
{
socket.ReceiveTimeout = 100;
socket.BindToAnonymousPort(IPAddress.Loopback);

var address = new SocketAddress(AddressFamily.InterNetwork);
var buffer = new byte[100];
int receivedLength;

for (int i = 0; i < 5; i++)
{
try
{
if (async)
{
using var cts = new CancellationTokenSource();
cts.CancelAfter(100);
receivedLength = socket.ReceiveFromAsync(buffer, SocketFlags.None, address, cts.Token).AsTask().GetAwaiter().GetResult();
}
else
{
receivedLength = socket.ReceiveFrom(buffer, SocketFlags.None, address);
}
Assert.Equal(0, receivedLength);
}
catch (SocketException ex) when (ex.SocketErrorCode == SocketError.TimedOut) { }
catch (OperationCanceledException) { }
}
}
}
}
}

0 comments on commit ffa1bea

Please sign in to comment.