public void JoinMulticastGroup(System.Net.IPAddress multicastAddr, System.Net.IPAddress localAddress) { }
public byte[] Receive([System.Diagnostics.CodeAnalysis.NotNullAttribute] ref System.Net.IPEndPoint? remoteEP) { throw null; }
public System.Threading.Tasks.Task<System.Net.Sockets.UdpReceiveResult> ReceiveAsync() { throw null; }
+ public System.Threading.Tasks.ValueTask<System.Net.Sockets.UdpReceiveResult> ReceiveAsync(System.Threading.CancellationToken cancellationToken) { throw null; }
public int Send(byte[] dgram, int bytes) { throw null; }
+ public int Send(System.ReadOnlySpan<byte> datagram) {throw null; }
public int Send(byte[] dgram, int bytes, System.Net.IPEndPoint? endPoint) { throw null; }
+ public int Send(System.ReadOnlySpan<byte> datagram, System.Net.IPEndPoint? endPoint) { throw null; }
public int Send(byte[] dgram, int bytes, string? hostname, int port) { throw null; }
+ public int Send(System.ReadOnlySpan<byte> datagram, string? hostname, int port) { throw null; }
public System.Threading.Tasks.Task<int> SendAsync(byte[] datagram, int bytes) { throw null; }
+ public System.Threading.Tasks.ValueTask<int> SendAsync(System.ReadOnlyMemory<byte> datagram, System.Threading.CancellationToken cancellationToken = default) { throw null; }
public System.Threading.Tasks.Task<int> SendAsync(byte[] datagram, int bytes, System.Net.IPEndPoint? endPoint) { throw null; }
+ public System.Threading.Tasks.ValueTask<int> SendAsync(System.ReadOnlyMemory<byte> datagram, System.Net.IPEndPoint? endPoint, System.Threading.CancellationToken cancellationToken = default) { throw null; }
public System.Threading.Tasks.Task<int> SendAsync(byte[] datagram, int bytes, string? hostname, int port) { throw null; }
+ public System.Threading.Tasks.ValueTask<int> SendAsync(System.ReadOnlyMemory<byte> datagram, string? hostname, int port, System.Threading.CancellationToken cancellationToken = default) { throw null; }
}
public partial struct UdpReceiveResult : System.IEquatable<System.Net.Sockets.UdpReceiveResult>
{
using System.Diagnostics.CodeAnalysis;
using System.Threading.Tasks;
using System.Runtime.Versioning;
+using System.Threading;
namespace System.Net.Sockets
{
public Task<int> SendAsync(byte[] datagram, int bytes) =>
SendAsync(datagram, bytes, null);
+ /// <summary>
+ /// Sends a UDP datagram asynchronously to a remote host.
+ /// </summary>
+ /// <param name="datagram">
+ /// An <see cref="ReadOnlyMemory{T}"/> of Type <see cref="byte"/> that specifies the UDP datagram that you intend to send.
+ /// </param>
+ /// <param name="cancellationToken">
+ /// The token to monitor for cancellation requests. The default value is None.
+ /// </param>
+ /// <returns>A <see cref="ValueTask{T}"/> that represents the asynchronous send operation. The value of its Result property contains the number of bytes sent.</returns>
+ /// <exception cref="ObjectDisposedException">The <see cref="UdpClient"/> is closed.</exception>
+ /// <exception cref="SocketException">An error occurred when accessing the socket.</exception>
+ public ValueTask<int> SendAsync(ReadOnlyMemory<byte> datagram, CancellationToken cancellationToken = default) =>
+ SendAsync(datagram, null, cancellationToken);
+
public Task<int> SendAsync(byte[] datagram, int bytes, string? hostname, int port) =>
SendAsync(datagram, bytes, GetEndpoint(hostname, port));
+ /// <summary>
+ /// Sends a UDP datagram asynchronously to a remote host.
+ /// </summary>
+ /// <param name="datagram">
+ /// An <see cref="ReadOnlyMemory{T}"/> of Type <see cref="byte"/> that specifies the UDP datagram that you intend to send.
+ /// </param>
+ /// <param name="hostname">
+ /// The name of the remote host to which you intend to send the datagram.
+ /// </param>
+ /// <param name="port">
+ /// The remote port number with which you intend to communicate.
+ /// </param>
+ /// <param name="cancellationToken">
+ /// The token to monitor for cancellation requests. The default value is None.
+ /// </param>
+ /// <returns>A <see cref="ValueTask{T}"/> that represents the asynchronous send operation. The value of its Result property contains the number of bytes sent.</returns>
+ /// <exception cref="InvalidOperationException">The <see cref="UdpClient"/> has already established a default remote host.</exception>
+ /// <exception cref="ObjectDisposedException">The <see cref="UdpClient"/> is closed.</exception>
+ /// <exception cref="SocketException">An error occurred when accessing the socket.</exception>
+ public ValueTask<int> SendAsync(ReadOnlyMemory<byte> datagram, string? hostname, int port, CancellationToken cancellationToken = default) =>
+ SendAsync(datagram, GetEndpoint(hostname, port), cancellationToken);
+
public Task<int> SendAsync(byte[] datagram, int bytes, IPEndPoint? endPoint)
{
ValidateDatagram(datagram, bytes, endPoint);
}
}
+ /// <summary>
+ /// Sends a UDP datagram asynchronously to a remote host.
+ /// </summary>
+ /// <param name="datagram">
+ /// An <see cref="ReadOnlyMemory{T}"/> of Type <see cref="byte"/> that specifies the UDP datagram that you intend to send.
+ /// </param>
+ /// <param name="endPoint">
+ /// An <see cref="IPEndPoint"/> that represents the host and port to which to send the datagram.
+ /// </param>
+ /// <param name="cancellationToken">
+ /// The token to monitor for cancellation requests. The default value is None.
+ /// </param>
+ /// <returns>A <see cref="ValueTask{T}"/> that represents the asynchronous send operation. The value of its Result property contains the number of bytes sent.</returns>
+ /// <exception cref="InvalidOperationException"><see cref="UdpClient"/> has already established a default remote host and <paramref name="endPoint"/> is not <see langword="null"/>.</exception>
+ /// <exception cref="ObjectDisposedException">The <see cref="UdpClient"/> is closed.</exception>
+ /// <exception cref="SocketException">An error occurred when accessing the socket.</exception>
+ public ValueTask<int> SendAsync(ReadOnlyMemory<byte> datagram, IPEndPoint? endPoint, CancellationToken cancellationToken = default)
+ {
+ ThrowIfDisposed();
+
+ if (endPoint is null)
+ {
+ return _clientSocket.SendAsync(datagram, SocketFlags.None, cancellationToken);
+ }
+ if (_active)
+ {
+ // Do not allow sending packets to arbitrary host when connected.
+ throw new InvalidOperationException(SR.net_udpconnected);
+ }
+ CheckForBroadcast(endPoint.Address);
+ return _clientSocket.SendToAsync(datagram, SocketFlags.None, endPoint, cancellationToken);
+ }
+
public Task<UdpReceiveResult> ReceiveAsync()
{
ThrowIfDisposed();
}
}
+ /// <summary>
+ /// Returns a UDP datagram asynchronously that was sent by a remote host.
+ /// </summary>
+ /// <param name="cancellationToken">
+ /// The token to monitor for cancellation requests.
+ /// </param>
+ /// <returns>A <see cref="ValueTask{TResult}"/> representing the asynchronous operation.</returns>
+ /// <exception cref="ObjectDisposedException">The underlying <see cref="Socket"/> has been closed.</exception>
+ /// <exception cref="SocketException">An error occurred when accessing the socket.</exception>
+ public ValueTask<UdpReceiveResult> ReceiveAsync(CancellationToken cancellationToken)
+ {
+ ThrowIfDisposed();
+
+ return WaitAndWrap(_clientSocket.ReceiveFromAsync(
+ _buffer,
+ SocketFlags.None,
+ _family == AddressFamily.InterNetwork ? IPEndPointStatics.Any : IPEndPointStatics.IPv6Any, cancellationToken));
+
+ async ValueTask<UdpReceiveResult> WaitAndWrap(ValueTask<SocketReceiveFromResult> task)
+ {
+ SocketReceiveFromResult result = await task.ConfigureAwait(false);
+
+ byte[] buffer = result.ReceivedBytes < MaxUDPSize ?
+ _buffer.AsSpan(0, result.ReceivedBytes).ToArray() :
+ _buffer;
+
+ return new UdpReceiveResult(buffer, (IPEndPoint)result.RemoteEndPoint);
+ }
+ }
+
private void CreateClientSocket()
{
// Common initialization code.
return Client.SendTo(dgram, 0, bytes, SocketFlags.None, endPoint);
}
-
- // Sends a UDP datagram to the specified port on the specified remote host.
- public int Send(byte[] dgram, int bytes, string? hostname, int port)
+ /// <summary>
+ /// Sends a UDP datagram to the host at the specified remote endpoint.
+ /// </summary>
+ /// <param name="datagram">
+ /// An <see cref="ReadOnlySpan{T}"/> of Type <see cref="byte"/> that specifies the UDP datagram that you intend to send.
+ /// </param>
+ /// <param name="endPoint">
+ /// An <see cref="IPEndPoint"/> that represents the host and port to which to send the datagram.
+ /// </param>
+ /// <returns>The number of bytes sent.</returns>
+ /// <exception cref="InvalidOperationException"><see cref="UdpClient"/> has already established a default remote host and <paramref name="endPoint"/> is not <see langword="null"/>.</exception>
+ /// <exception cref="ObjectDisposedException"><see cref="UdpClient"/> is closed.</exception>
+ /// <exception cref="SocketException">An error occurred when accessing the socket.</exception>
+ public int Send(ReadOnlySpan<byte> datagram, IPEndPoint? endPoint)
{
ThrowIfDisposed();
- if (dgram == null)
- {
- throw new ArgumentNullException(nameof(dgram));
- }
- if (_active && ((hostname != null) || (port != 0)))
+ if (_active && endPoint != null)
{
// Do not allow sending packets to arbitrary host when connected
throw new InvalidOperationException(SR.net_udpconnected);
}
- if (hostname == null || port == 0)
- {
- return Client.Send(dgram, 0, bytes, SocketFlags.None);
- }
-
- IPAddress[] addresses = Dns.GetHostAddresses(hostname);
-
- int i = 0;
- for (; i < addresses.Length && !IsAddressFamilyCompatible(addresses[i].AddressFamily); i++)
+ if (endPoint == null)
{
- ; // just count the addresses
+ return Client.Send(datagram, SocketFlags.None);
}
- if (addresses.Length == 0 || i == addresses.Length)
- {
- throw new ArgumentException(SR.net_invalidAddressList, nameof(hostname));
- }
+ CheckForBroadcast(endPoint.Address);
- CheckForBroadcast(addresses[i]);
- IPEndPoint ipEndPoint = new IPEndPoint(addresses[i], port);
- return Client.SendTo(dgram, 0, bytes, SocketFlags.None, ipEndPoint);
+ return Client.SendTo(datagram, SocketFlags.None, endPoint);
}
+ // Sends a UDP datagram to the specified port on the specified remote host.
+ public int Send(byte[] dgram, int bytes, string? hostname, int port) => Send(dgram, bytes, GetEndpoint(hostname, port));
+
+ /// <summary>
+ /// Sends a UDP datagram to a specified port on a specified remote host.
+ /// </summary>
+ /// <param name="datagram">
+ /// An <see cref="ReadOnlySpan{T}"/> of Type <see cref="byte"/> that specifies the UDP datagram that you intend to send.
+ /// </param>
+ /// <param name="hostname">
+ /// The name of the remote host to which you intend to send the datagram.
+ /// </param>
+ /// <param name="port">
+ /// The remote port number with which you intend to communicate.
+ /// </param>
+ /// <returns>The number of bytes sent.</returns>
+ /// <exception cref="InvalidOperationException">The <see cref="UdpClient"/> has already established a default remote host.</exception>
+ /// <exception cref="ObjectDisposedException">The <see cref="UdpClient"/> is closed.</exception>
+ /// <exception cref="SocketException">An error occurred when accessing the socket.</exception>
+ public int Send(ReadOnlySpan<byte> datagram, string? hostname, int port) => Send(datagram, GetEndpoint(hostname, port));
// Sends a UDP datagram to a remote host.
public int Send(byte[] dgram, int bytes)
return Client.Send(dgram, 0, bytes, SocketFlags.None);
}
+ /// <summary>
+ /// Sends a UDP datagram to a remote host.
+ /// </summary>
+ /// <param name="datagram">
+ /// An <see cref="ReadOnlySpan{T}"/> of Type <see cref="byte"/> that specifies the UDP datagram that you intend to send.
+ /// </param>
+ /// <returns>The number of bytes sent.</returns>
+ /// <exception cref="InvalidOperationException">The <see cref="UdpClient"/> has not established a default remote host.</exception>
+ /// <exception cref="ObjectDisposedException">The <see cref="UdpClient"/> is closed.</exception>
+ /// <exception cref="SocketException">An error occurred when accessing the socket.</exception>
+ public int Send(ReadOnlySpan<byte> datagram)
+ {
+ ThrowIfDisposed();
+
+ if (!_active)
+ {
+ // only allowed on connected socket
+ throw new InvalidOperationException(SR.net_notconnected);
+ }
+
+ return Client.Send(datagram, SocketFlags.None);
+ }
+
private void ThrowIfDisposed()
{
if (_disposed)
namespace System.Net.Sockets
{
/// <summary>
- /// Presents UDP receive result information from a call to the <see cref="UdpClient.ReceiveAsync"/> method
+ /// Presents UDP receive result information from a call to the <see cref="UdpClient.ReceiveAsync()"/> and <see cref="UdpClient.ReceiveAsync(System.Threading.CancellationToken)"/> method
/// </summary>
public struct UdpReceiveResult : IEquatable<UdpReceiveResult>
{
{
[OuterLoop]
[Theory]
- [MemberData(nameof(Loopbacks))]
- public async Task SendToRecvFromAsync_Datagram_UDP_UdpClient(IPAddress loopbackAddress)
+ [MemberData(nameof(LoopbacksAndUseMemory))]
+ public async Task SendToRecvFromAsync_Datagram_UDP_UdpClient(IPAddress loopbackAddress, bool useMemoryOverload)
{
IPAddress leftAddress = loopbackAddress, rightAddress = loopbackAddress;
random.NextBytes(sendBuffer);
sendBuffer[0] = (byte)sentDatagrams;
- int sent = await right.SendAsync(sendBuffer, DatagramSize, leftEndpoint);
+ int sent = useMemoryOverload ? await right.SendAsync(new ReadOnlyMemory<byte>(sendBuffer), leftEndpoint) : await right.SendAsync(sendBuffer, DatagramSize, leftEndpoint);
Assert.True(receiverAck.Wait(AckTimeout));
receiverAck.Reset();
}
}
}
+
+ public static readonly object[][] LoopbacksAndUseMemory = new object[][]
+ {
+ new object[] { IPAddress.IPv6Loopback, true },
+ new object[] { IPAddress.IPv6Loopback, false },
+ new object[] { IPAddress.Loopback, true },
+ new object[] { IPAddress.Loopback, false },
+ };
}
}
await new SendReceive_Apm(null).SendRecv_Stream_TCP(IPAddress.Loopback, false).ConfigureAwait(false);
await new SendReceive_Apm(null).SendRecv_Stream_TCP(IPAddress.Loopback, true).ConfigureAwait(false);
- await new SendReceiveUdpClient().SendToRecvFromAsync_Datagram_UDP_UdpClient(IPAddress.Loopback).ConfigureAwait(false);
- await new SendReceiveUdpClient().SendToRecvFromAsync_Datagram_UDP_UdpClient(IPAddress.Loopback).ConfigureAwait(false);
+ await new SendReceiveUdpClient().SendToRecvFromAsync_Datagram_UDP_UdpClient(IPAddress.Loopback, false).ConfigureAwait(false);
+ await new SendReceiveUdpClient().SendToRecvFromAsync_Datagram_UDP_UdpClient(IPAddress.Loopback, false).ConfigureAwait(false);
await new NetworkStreamTest().CopyToAsync_AllDataCopied(4096, true).ConfigureAwait(false);
await new NetworkStreamTest().Timeout_Roundtrips().ConfigureAwait(false);
AssertExtensions.Throws<ArgumentNullException>("localEP", () => new UdpClient(null));
}
- [OuterLoop]
[Fact]
public void Ctor_CanSend()
{
}
}
- [OuterLoop]
[Fact]
public void Ctor_Int_CanSend()
{
}
}
- [OuterLoop]
[Fact]
public void Ctor_IntAddressFamily_IPv4_CanSend()
{
}
}
- [OuterLoop]
[Fact]
public void Ctor_IntAddressFamily_IPv6_CanSend()
{
}
}
- [OuterLoop]
[Fact]
public void Ctor_IPEndPoint_CanSend()
{
}
}
- [OuterLoop]
[Fact]
public void Ctor_StringInt_CanSend()
{
Assert.Throws<ObjectDisposedException>(() => udpClient.Send(null, 0, remoteEP));
Assert.Throws<ObjectDisposedException>(() => udpClient.Send(null, 0));
Assert.Throws<ObjectDisposedException>(() => udpClient.Send(null, 0, "localhost", 0));
+
+ Assert.Throws<ObjectDisposedException>(() => udpClient.Send(new ReadOnlySpan<byte>(), remoteEP));
+ Assert.Throws<ObjectDisposedException>(() => udpClient.Send(new ReadOnlySpan<byte>()));
+ Assert.Throws<ObjectDisposedException>(() => udpClient.Send(new ReadOnlySpan<byte>(), "localhost", 0));
+
+ Assert.Throws<ObjectDisposedException>(() => {udpClient.SendAsync(null, 0, remoteEP);});
+ Assert.Throws<ObjectDisposedException>(() => {udpClient.SendAsync(null, 0);});
+ Assert.Throws<ObjectDisposedException>(() => {udpClient.SendAsync(null, 0, "localhost", 0);});
+
+ Assert.Throws<ObjectDisposedException>(() => udpClient.SendAsync(new ReadOnlyMemory<byte>(), remoteEP));
+ Assert.Throws<ObjectDisposedException>(() => udpClient.SendAsync(new ReadOnlyMemory<byte>()));
+ Assert.Throws<ObjectDisposedException>(() => udpClient.SendAsync(new ReadOnlyMemory<byte>(), "localhost", 0));
+
+ Assert.Throws<ObjectDisposedException>(() => {udpClient.ReceiveAsync();});
+ Assert.Throws<ObjectDisposedException>(() => udpClient.ReceiveAsync(default));
}
[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsPreciseGcSupported))]
}
}
- [OuterLoop]
[Fact]
public void BeginSend_NegativeBytes_Throws()
{
}
}
- [OuterLoop]
[Fact]
public void BeginSend_BytesMoreThanArrayLength_Throws()
{
}
}
- [OuterLoop]
[Fact]
public void BeginSend_AsyncOperationCompletes_Success()
{
AssertExtensions.Throws<ArgumentNullException>("dgram", () => udpClient.Send(null, 0, "localhost", 0));
AssertExtensions.Throws<ArgumentNullException>("dgram", () => udpClient.Send(null, 0, new IPEndPoint(IPAddress.Loopback, 0)));
Assert.Throws<InvalidOperationException>(() => udpClient.Send(new byte[1], 1));
+ Assert.Throws<InvalidOperationException>(() => udpClient.Send(new ReadOnlySpan<byte>(new byte[1])));
udpClient.Active = true;
Assert.Throws<InvalidOperationException>(() => udpClient.Send(new byte[1], 1, new IPEndPoint(IPAddress.Loopback, 0)));
+ Assert.Throws<InvalidOperationException>(() => udpClient.Send(new ReadOnlySpan<byte>(new byte[1]), new IPEndPoint(IPAddress.Loopback, 0)));
+ Assert.Throws<InvalidOperationException>(() => {udpClient.SendAsync(new byte[1], 1, new IPEndPoint(IPAddress.Loopback, 0));});
+ Assert.Throws<InvalidOperationException>(() => udpClient.SendAsync(new ReadOnlyMemory<byte>(new byte[1]), new IPEndPoint(IPAddress.Loopback, 0)));
}
}
using (var udpClient = new UdpClient("localhost", 0))
{
Assert.Throws<InvalidOperationException>(() => udpClient.Send(new byte[1], 1, "localhost", 0));
+ Assert.Throws<InvalidOperationException>(() => udpClient.Send(new ReadOnlySpan<byte>(new byte[1]), "localhost", 0));
+ Assert.Throws<InvalidOperationException>(() => {udpClient.SendAsync(new byte[1], 1, "localhost", 0);});
+ Assert.Throws<InvalidOperationException>(() => udpClient.SendAsync(new ReadOnlyMemory<byte>(new byte[1]), "localhost", 0));
+
+ Assert.Throws<InvalidOperationException>(() => udpClient.Send(new byte[1], 1, null, UnusedPort));
+ Assert.Throws<InvalidOperationException>(() => udpClient.Send(new ReadOnlySpan<byte>(new byte[1]), null, UnusedPort));
+ Assert.Throws<InvalidOperationException>(() => {udpClient.SendAsync(new byte[1], 1, null, UnusedPort);});
+ Assert.Throws<InvalidOperationException>(() => udpClient.SendAsync(new ReadOnlyMemory<byte>(new byte[1]), null, UnusedPort));
}
}
- [OuterLoop]
[Fact]
public void Client_Idempotent()
{
}
}
- [OuterLoop]
[Fact]
public async Task ConnectAsync_StringHost_Success()
{
}
}
- [OuterLoop]
[Fact]
public async Task ConnectAsync_IPAddressHost_Success()
{
}
}
- [OuterLoop]
[Fact]
public void Connect_StringHost_Success()
{
}
}
- [OuterLoop]
[Fact]
public void Connect_IPAddressHost_Success()
{
_waitHandle.Set();
}
- [OuterLoop]
[Theory]
[PlatformSpecific(TestPlatforms.Windows)] // Udp.AllowNatTraversal only supported on Windows
[InlineData(true, IPProtectionLevel.Unrestricted)]
}
}
- [OuterLoop]
[Theory]
[PlatformSpecific(TestPlatforms.AnyUnix)] // Udp.AllowNatTraversal throws PNSE on Unix
[InlineData(true)]
}
}
- [OuterLoop]
[Theory]
[InlineData(false)]
[InlineData(true)]
using (var sender = new UdpClient(new IPEndPoint(address, 0)))
{
sender.Send(new byte[1], 1, new IPEndPoint(address, ((IPEndPoint)receiver.Client.LocalEndPoint).Port));
+ AssertReceive(receiver);
- IPEndPoint remoteEP = null;
- byte[] data = receiver.Receive(ref remoteEP);
- Assert.NotNull(remoteEP);
- Assert.InRange(data.Length, 1, int.MaxValue);
+ sender.Send(new ReadOnlySpan<byte>(new byte[1]), new IPEndPoint(address, ((IPEndPoint)receiver.Client.LocalEndPoint).Port));
+ AssertReceive(receiver);
+ }
+ }
+
+ [Theory]
+ [InlineData(false)]
+ [InlineData(true)]
+ [PlatformSpecific(TestPlatforms.Windows)] // "localhost" resolves to IPv4 & IPV6 on Windows, but may resolve to only one of those on Unix
+ public void Send_Receive_With_HostName_Success(bool ipv4)
+ {
+ IPAddress address = ipv4 ? IPAddress.Loopback : IPAddress.IPv6Loopback;
+
+ using (var receiver = new UdpClient(new IPEndPoint(address, 0)))
+ using (var sender = new UdpClient(new IPEndPoint(address, 0)))
+ {
+ sender.Send(new byte[1], 1, "localhost", ((IPEndPoint)receiver.Client.LocalEndPoint).Port);
+ AssertReceive(receiver);
+
+ sender.Send(new ReadOnlySpan<byte>(new byte[1]), "localhost", ((IPEndPoint)receiver.Client.LocalEndPoint).Port);
+ AssertReceive(receiver);
}
}
[Fact]
[PlatformSpecific(TestPlatforms.Windows)] // "localhost" resolves to IPv4 & IPV6 on Windows, but may resolve to only one of those on Unix
- [OuterLoop]
public void Send_Receive_Connected_Success()
{
using (var receiver = new UdpClient("localhost", 0))
using (var sender = new UdpClient("localhost", ((IPEndPoint)receiver.Client.LocalEndPoint).Port))
{
sender.Send(new byte[1], 1);
+ AssertReceive(receiver);
- IPEndPoint remoteEP = null;
- byte[] data = receiver.Receive(ref remoteEP);
- Assert.NotNull(remoteEP);
- Assert.InRange(data.Length, 1, int.MaxValue);
+ sender.Send(new ReadOnlySpan<byte>(new byte[1]));
+ AssertReceive(receiver);
}
}
- [OuterLoop]
+ private static void AssertReceive(UdpClient receiver)
+ {
+ IPEndPoint remoteEP = null;
+ byte[] data = receiver.Receive(ref remoteEP);
+ Assert.NotNull(remoteEP);
+ Assert.InRange(data.Length, 1, int.MaxValue);
+ }
+
[Theory]
[InlineData(false)]
[InlineData(true)]
}
}
- [OuterLoop]
[Theory]
[InlineData(false)]
[InlineData(true)]
[Fact]
[PlatformSpecific(TestPlatforms.Windows)] // "localhost" resolves to IPv4 & IPV6 on Windows, but may resolve to only one of those on Unix
- [OuterLoop]
public void BeginEndSend_BeginEndReceive_Connected_Success()
{
using (var receiver = new UdpClient("localhost", 0))
}
}
- [OuterLoop]
[Theory]
[InlineData(false)]
[InlineData(true)]
using (var sender = new UdpClient(new IPEndPoint(address, 0)))
{
await sender.SendAsync(new byte[1], 1, new IPEndPoint(address, ((IPEndPoint)receiver.Client.LocalEndPoint).Port));
+ await AssertReceiveAsync(receiver);
+
+ await sender.SendAsync(new ReadOnlyMemory<byte>(new byte[1]), new IPEndPoint(address, ((IPEndPoint)receiver.Client.LocalEndPoint).Port));
+ await AssertReceiveAsync(receiver);
+ }
+ }
- UdpReceiveResult result = await receiver.ReceiveAsync();
- Assert.NotNull(result.RemoteEndPoint);
- Assert.NotNull(result.Buffer);
- Assert.InRange(result.Buffer.Length, 1, int.MaxValue);
+ [Theory]
+ [InlineData(false)]
+ [InlineData(true)]
+ [PlatformSpecific(TestPlatforms.Windows)] // "localhost" resolves to IPv4 & IPV6 on Windows, but may resolve to only one of those on Unix
+ public async Task SendAsync_ReceiveAsync_With_HostName_Success(bool ipv4)
+ {
+ IPAddress address = ipv4 ? IPAddress.Loopback : IPAddress.IPv6Loopback;
+
+ using (var receiver = new UdpClient(new IPEndPoint(address, 0)))
+ using (var sender = new UdpClient(new IPEndPoint(address, 0)))
+ {
+ await sender.SendAsync(new byte[1], "localhost", ((IPEndPoint)receiver.Client.LocalEndPoint).Port);
+ await AssertReceiveAsync(receiver);
+
+ await sender.SendAsync(new ReadOnlyMemory<byte>(new byte[1]), "localhost", ((IPEndPoint)receiver.Client.LocalEndPoint).Port);
+ await AssertReceiveAsync(receiver);
+ }
+ }
+
+ [Theory]
+ [InlineData(false)]
+ [InlineData(true)]
+ public async Task ReceiveAsync_Cancel_Throw(bool ipv4)
+ {
+ IPAddress address = ipv4 ? IPAddress.Loopback : IPAddress.IPv6Loopback;
+
+ using (var receiver = new UdpClient(new IPEndPoint(address, 0)))
+ {
+ using (var timeoutCts = new CancellationTokenSource(1))
+ {
+ await Assert.ThrowsAnyAsync<OperationCanceledException>(() => receiver.ReceiveAsync(timeoutCts.Token).AsTask());
+ }
}
}
[Fact]
[PlatformSpecific(TestPlatforms.Windows)] // "localhost" resolves to IPv4 & IPV6 on Windows, but may resolve to only one of those on Unix
- [OuterLoop]
public async Task SendAsync_ReceiveAsync_Connected_Success()
{
using (var receiver = new UdpClient("localhost", 0))
using (var sender = new UdpClient("localhost", ((IPEndPoint)receiver.Client.LocalEndPoint).Port))
{
await sender.SendAsync(new byte[1], 1);
+ await AssertReceiveAsync(receiver);
+
+ await sender.SendAsync(new ReadOnlyMemory<byte>(new byte[1]));
+ await AssertReceiveAsync(receiver);
+
+ await sender.SendAsync(new ReadOnlyMemory<byte>(new byte[1]), null);
+ await AssertReceiveAsync(receiver);
+
+ await sender.SendAsync(new ReadOnlyMemory<byte>(new byte[1]), null, 0);
+ await AssertReceiveAsync(receiver);
+ }
+ }
+
+ private static async Task AssertReceiveAsync(UdpClient receiver)
+ {
+ UdpReceiveResult result = await receiver.ReceiveAsync();
+ Assert.NotNull(result.RemoteEndPoint);
+ Assert.NotNull(result.Buffer);
+ Assert.InRange(result.Buffer.Length, 1, int.MaxValue);
+ }
+
+ [Fact]
+ [PlatformSpecific(TestPlatforms.Windows)] // "localhost" resolves to IPv4 & IPV6 on Windows, but may resolve to only one of those on Unix
+ public async Task SendAsync_Connected_PreCanceled_Throws()
+ {
+ using (var receiver = new UdpClient("localhost", 0))
+ using (var sender = new UdpClient("localhost", ((IPEndPoint)receiver.Client.LocalEndPoint).Port))
+ {
+ await Assert.ThrowsAnyAsync<OperationCanceledException>(() => sender.SendAsync(new ReadOnlyMemory<byte>(new byte[1]), new CancellationToken(true)).AsTask());
+ }
+ }
- UdpReceiveResult result = await receiver.ReceiveAsync();
- Assert.NotNull(result.RemoteEndPoint);
- Assert.NotNull(result.Buffer);
- Assert.InRange(result.Buffer.Length, 1, int.MaxValue);
+ [Theory]
+ [InlineData(false)]
+ [InlineData(true)]
+ [PlatformSpecific(TestPlatforms.Windows)] // "localhost" resolves to IPv4 & IPV6 on Windows, but may resolve to only one of those on Unix
+ public async Task SendAsync_With_HostName_PreCanceled_Throws(bool ipv4)
+ {
+ IPAddress address = ipv4 ? IPAddress.Loopback : IPAddress.IPv6Loopback;
+
+ using (var receiver = new UdpClient(new IPEndPoint(address, 0)))
+ using (var sender = new UdpClient(new IPEndPoint(address, 0)))
+ {
+ await Assert.ThrowsAnyAsync<OperationCanceledException>(() => sender.SendAsync(new ReadOnlyMemory<byte>(new byte[1]), "localhost", ((IPEndPoint)receiver.Client.LocalEndPoint).Port, new CancellationToken(true)).AsTask());
+ }
+ }
+
+ [Theory]
+ [InlineData(false)]
+ [InlineData(true)]
+ public async Task SendAsync_PreCanceled_Throws(bool ipv4)
+ {
+ IPAddress address = ipv4 ? IPAddress.Loopback : IPAddress.IPv6Loopback;
+
+ using (var receiver = new UdpClient(new IPEndPoint(address, 0)))
+ using (var sender = new UdpClient(new IPEndPoint(address, 0)))
+ {
+ await Assert.ThrowsAnyAsync<OperationCanceledException>(() => sender.SendAsync(new ReadOnlyMemory<byte>(new byte[1]), new IPEndPoint(address, ((IPEndPoint)receiver.Client.LocalEndPoint).Port), new CancellationToken(true)).AsTask());
}
}