From e0fbfb458e4808c3a853c231c1291bd38b48773e Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Mon, 11 Jan 2021 17:59:39 +0100 Subject: [PATCH 1/8] extend SocketTestHelper --- .../tests/FunctionalTests/SocketTestHelper.cs | 64 ++++++++++++++++++- 1 file changed, 62 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SocketTestHelper.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SocketTestHelper.cs index b6ff51778cc528..811aa80774ecd2 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SocketTestHelper.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SocketTestHelper.cs @@ -27,6 +27,8 @@ public abstract class SocketHelperBase public abstract Task ReceiveAsync(Socket s, ArraySegment buffer); public abstract Task ReceiveFromAsync( Socket s, ArraySegment buffer, EndPoint endPoint); + public abstract Task ReceiveMessageFromAsync( + Socket s, ArraySegment buffer, EndPoint endPoint); public abstract Task ReceiveAsync(Socket s, IList> bufferList); public abstract Task SendAsync(Socket s, ArraySegment buffer); public abstract Task SendAsync(Socket s, IList> bufferList); @@ -68,6 +70,20 @@ public override Task ReceiveFromAsync(Socket s, ArraySe RemoteEndPoint = endPoint }; }); + public override Task ReceiveMessageFromAsync(Socket s, ArraySegment buffer, EndPoint endPoint) => + Task.Run(() => + { + SocketFlags socketFlags = SocketFlags.None; + IPPacketInformation ipPacketInformation; + int received = s.ReceiveMessageFrom(buffer.Array, buffer.Offset, buffer.Count, ref socketFlags, ref endPoint, out ipPacketInformation); + return new SocketReceiveMessageFromResult + { + ReceivedBytes = received, + SocketFlags = socketFlags, + RemoteEndPoint = endPoint, + PacketInformation = ipPacketInformation + }; + }); public override Task SendAsync(Socket s, ArraySegment buffer) => Task.Run(() => s.Send(buffer.Array, buffer.Offset, buffer.Count, SocketFlags.None)); public override Task SendAsync(Socket s, IList> bufferList) => @@ -142,6 +158,29 @@ public override Task ReceiveFromAsync(Socket s, ArraySe }, null); return tcs.Task; } + public override Task ReceiveMessageFromAsync(Socket s, ArraySegment buffer, EndPoint endPoint) + { + var tcs = new TaskCompletionSource(); + SocketFlags socketFlags = SocketFlags.None; + s.BeginReceiveMessageFrom(buffer.Array, buffer.Offset, buffer.Count, socketFlags, ref endPoint, iar => + { + try + { + int receivedBytes = s.EndReceiveMessageFrom(iar, ref socketFlags, ref endPoint, out IPPacketInformation ipPacketInformation); + var result = new SocketReceiveMessageFromResult + { + ReceivedBytes = receivedBytes, + SocketFlags = socketFlags, + RemoteEndPoint = endPoint, + PacketInformation = ipPacketInformation + }; + tcs.TrySetResult(result); + } + catch (Exception e) { tcs.TrySetException(e); } + + }, null); + return tcs.Task; + } public override Task SendAsync(Socket s, ArraySegment buffer) => Task.Factory.FromAsync((callback, state) => s.BeginSend(buffer.Array, buffer.Offset, buffer.Count, SocketFlags.None, callback, state), @@ -174,6 +213,8 @@ public override Task ReceiveAsync(Socket s, IList> buffe s.ReceiveAsync(bufferList, SocketFlags.None); public override Task ReceiveFromAsync(Socket s, ArraySegment buffer, EndPoint endPoint) => s.ReceiveFromAsync(buffer, SocketFlags.None, endPoint); + public override Task ReceiveMessageFromAsync(Socket s, ArraySegment buffer, EndPoint endPoint) => + s.ReceiveMessageFromAsync(buffer, SocketFlags.None, endPoint); public override Task SendAsync(Socket s, ArraySegment buffer) => s.SendAsync(buffer, SocketFlags.None); public override Task SendAsync(Socket s, IList> bufferList) => @@ -204,6 +245,8 @@ public override Task ReceiveAsync(Socket s, IList> buffe s.ReceiveAsync(bufferList, SocketFlags.None); public override Task ReceiveFromAsync(Socket s, ArraySegment buffer, EndPoint endPoint) => s.ReceiveFromAsync(buffer, SocketFlags.None, endPoint); + public override Task ReceiveMessageFromAsync(Socket s, ArraySegment buffer, EndPoint endPoint) => + s.ReceiveMessageFromAsync(buffer, SocketFlags.None, endPoint); public override Task SendAsync(Socket s, ArraySegment buffer) => s.SendAsync(buffer, SocketFlags.None, _cts.Token).AsTask(); public override Task SendAsync(Socket s, IList> bufferList) => @@ -265,6 +308,21 @@ public override Task ReceiveFromAsync(Socket s, ArraySe e.RemoteEndPoint = endPoint; return s.ReceiveFromAsync(e); }); + public override Task ReceiveMessageFromAsync(Socket s, ArraySegment buffer, EndPoint endPoint) => + InvokeAsync(s, + e => new SocketReceiveMessageFromResult + { + ReceivedBytes = e.BytesTransferred, + RemoteEndPoint = e.RemoteEndPoint, + SocketFlags = e.SocketFlags, + PacketInformation = e.ReceiveMessageFromPacketInfo + }, + e => + { + e.SetBuffer(buffer.Array, buffer.Offset, buffer.Count); + e.RemoteEndPoint = endPoint; + return s.ReceiveMessageFromAsync(e); + }); public override Task SendAsync(Socket s, ArraySegment buffer) => InvokeAsync(s, e => e.BytesTransferred, e => { @@ -331,8 +389,10 @@ public SocketTestHelperBase(ITestOutputHelper output) public Task ConnectAsync(Socket s, EndPoint endPoint) => _socketHelper.ConnectAsync(s, endPoint); public Task MultiConnectAsync(Socket s, IPAddress[] addresses, int port) => _socketHelper.MultiConnectAsync(s, addresses, port); public Task ReceiveAsync(Socket s, ArraySegment buffer) => _socketHelper.ReceiveAsync(s, buffer); - public Task ReceiveFromAsync( - Socket s, ArraySegment buffer, EndPoint endPoint) => _socketHelper.ReceiveFromAsync(s, buffer, endPoint); + public Task ReceiveFromAsync(Socket s, ArraySegment buffer, EndPoint endPoint) => + _socketHelper.ReceiveFromAsync(s, buffer, endPoint); + public Task ReceiveMessageFromAsync(Socket s, ArraySegment buffer, EndPoint endPoint) => + _socketHelper.ReceiveMessageFromAsync(s, buffer, endPoint); public Task ReceiveAsync(Socket s, IList> bufferList) => _socketHelper.ReceiveAsync(s, bufferList); public Task SendAsync(Socket s, ArraySegment buffer) => _socketHelper.SendAsync(s, buffer); public Task SendAsync(Socket s, IList> bufferList) => _socketHelper.SendAsync(s, bufferList); From a5543ad2c6c95d36c837b2927501c4f7686d2401 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Mon, 11 Jan 2021 19:16:41 +0100 Subject: [PATCH 2/8] SocketHelperMemoryNativeTask: implement UDP methods --- .../tests/FunctionalTests/SocketTestHelper.cs | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SocketTestHelper.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SocketTestHelper.cs index 811aa80774ecd2..8f1c9a94d9ac40 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SocketTestHelper.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SocketTestHelper.cs @@ -451,6 +451,7 @@ public override async Task ReceiveAsync(Socket s, ArraySegment buffer return bytesReceived; } } + public override async Task SendAsync(Socket s, ArraySegment buffer) { using (var m = new NativeMemoryManager(buffer.Count)) @@ -459,6 +460,35 @@ public override async Task SendAsync(Socket s, ArraySegment buffer) return await s.SendAsync(m.Memory, SocketFlags.None).ConfigureAwait(false); } } + + public override async Task SendToAsync(Socket s, ArraySegment buffer, EndPoint endPoint) + { + using (var m = new NativeMemoryManager(buffer.Count)) + { + buffer.AsSpan().CopyTo(m.Memory.Span); + return await s.SendToAsync(m.Memory, SocketFlags.None, endPoint).ConfigureAwait(false); + } + } + + public override async Task ReceiveFromAsync(Socket s, ArraySegment buffer, EndPoint endPoint) + { + using (var m = new NativeMemoryManager(buffer.Count)) + { + SocketReceiveFromResult result = await s.ReceiveFromAsync(m.Memory, SocketFlags.None, endPoint).ConfigureAwait(false); + m.Memory.Span.Slice(0, result.ReceivedBytes).CopyTo(buffer.AsSpan()); + return result; + } + } + + public override async Task ReceiveMessageFromAsync(Socket s, ArraySegment buffer, EndPoint endPoint) + { + using (var m = new NativeMemoryManager(buffer.Count)) + { + SocketReceiveMessageFromResult result = await s.ReceiveMessageFromAsync(m.Memory, SocketFlags.None, endPoint).ConfigureAwait(false); + m.Memory.Span.Slice(0, result.ReceivedBytes).CopyTo(buffer.AsSpan()); + return result; + } + } } // From 83d773a20f1df984a37cfc9122e5a4f6526226cd Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Mon, 11 Jan 2021 19:34:42 +0100 Subject: [PATCH 3/8] unified test for ReceiveSentMessages_Success --- .../tests/System/Net/Sockets/Fletcher32.cs | 2 + .../FunctionalTests/ReceiveMessageFrom.cs | 94 ++++++++++++++++++- 2 files changed, 95 insertions(+), 1 deletion(-) diff --git a/src/libraries/Common/tests/System/Net/Sockets/Fletcher32.cs b/src/libraries/Common/tests/System/Net/Sockets/Fletcher32.cs index 15451b84964056..91d1c118813fe2 100644 --- a/src/libraries/Common/tests/System/Net/Sockets/Fletcher32.cs +++ b/src/libraries/Common/tests/System/Net/Sockets/Fletcher32.cs @@ -61,5 +61,7 @@ public static uint Checksum(byte[] bytes, int offset, int count) fletcher32.Add(bytes, offset, count); return fletcher32.Sum; } + + public static uint Checksum(byte[] bytes) => Checksum(bytes, 0, bytes.Length); } } diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/ReceiveMessageFrom.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/ReceiveMessageFrom.cs index c4866b8ae78905..2c26edecb775bd 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/ReceiveMessageFrom.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/ReceiveMessageFrom.cs @@ -3,11 +3,58 @@ using System.Collections.Generic; using System.Threading; +using System.Threading.Tasks; using Xunit; +using Xunit.Abstractions; namespace System.Net.Sockets.Tests { - public class ReceiveMessageFrom + public abstract class ReceiveMessageFrom : SocketTestHelperBase where T : SocketHelperBase, new() + { + protected ReceiveMessageFrom(ITestOutputHelper output) : base(output) { } + + [Theory] + [InlineData(false)] + [InlineData(true)] + public async Task ReceiveSentMessages_Success(bool ipv4) + { + const int DatagramSize = 256; + const int DatagramsToSend = 16; + + IPAddress address = ipv4 ? IPAddress.Loopback : IPAddress.IPv6Loopback; + using Socket receiver = new Socket(address.AddressFamily, SocketType.Dgram, ProtocolType.Udp); + using Socket sender = new Socket(address.AddressFamily, SocketType.Dgram, ProtocolType.Udp); + + receiver.SetSocketOption(ipv4 ? SocketOptionLevel.IP : SocketOptionLevel.IPv6, SocketOptionName.PacketInformation, true); + ConfigureNonBlocking(sender); + ConfigureNonBlocking(receiver); + + receiver.BindToAnonymousPort(address); + sender.BindToAnonymousPort(address); + + byte[] sendBuffer = new byte[DatagramSize]; + byte[] receiveBuffer = new byte[DatagramSize]; + Random rnd = new Random(0); + + IPEndPoint remoteEp = new IPEndPoint(ipv4 ? IPAddress.Any : IPAddress.IPv6Any, 0); + + for (int i = 0; i < DatagramsToSend; i++) + { + rnd.NextBytes(sendBuffer); + sender.SendTo(sendBuffer, receiver.LocalEndPoint); + + SocketReceiveMessageFromResult result = await ReceiveMessageFromAsync(receiver, receiveBuffer, remoteEp); + IPPacketInformation packetInformation = result.PacketInformation; + + Assert.Equal(DatagramSize, result.ReceivedBytes); + Assert.Equal(Fletcher32.Checksum(sendBuffer), Fletcher32.Checksum(receiveBuffer)); + Assert.Equal(sender.LocalEndPoint, result.RemoteEndPoint); + Assert.Equal(((IPEndPoint)sender.LocalEndPoint).Address, packetInformation.Address); + } + } + } + + public class ReceiveMessageFrom_Old { [OuterLoop] [Theory] @@ -203,4 +250,49 @@ public void Success_EventArgs(bool ipv4, int bufferMode) } } } + + public sealed class ReceiveMessageFrom_Sync : ReceiveMessageFrom + { + public ReceiveMessageFrom_Sync(ITestOutputHelper output) : base(output) { } + } + + public sealed class ReceiveMessageFrom_SyncForceNonBlocking : ReceiveMessageFrom + { + public ReceiveMessageFrom_SyncForceNonBlocking(ITestOutputHelper output) : base(output) { } + } + + public sealed class ReceiveMessageFrom_Apm : ReceiveMessageFrom + { + public ReceiveMessageFrom_Apm(ITestOutputHelper output) : base(output) { } + } + + public sealed class ReceiveMessageFrom_Task : ReceiveMessageFrom + { + public ReceiveMessageFrom_Task(ITestOutputHelper output) : base(output) { } + } + + public sealed class ReceiveMessageFrom_Eap : ReceiveMessageFrom + { + public ReceiveMessageFrom_Eap(ITestOutputHelper output) : base(output) { } + } + + public sealed class ReceiveMessageFrom_SpanSync : ReceiveMessageFrom + { + public ReceiveMessageFrom_SpanSync(ITestOutputHelper output) : base(output) { } + } + + public sealed class ReceiveMessageFrom_SpanSyncForceNonBlocking : ReceiveMessageFrom + { + public ReceiveMessageFrom_SpanSyncForceNonBlocking(ITestOutputHelper output) : base(output) { } + } + + public sealed class ReceiveMessageFrom_MemoryArrayTask : ReceiveMessageFrom + { + public ReceiveMessageFrom_MemoryArrayTask(ITestOutputHelper output) : base(output) { } + } + + public sealed class ReceiveMessageFrom_MemoryNativeTask : ReceiveMessageFrom + { + public ReceiveMessageFrom_MemoryNativeTask(ITestOutputHelper output) : base(output) { } + } } From ba1f72c8b4bc39ca8f70c71b22f03bdc8a2d2841 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Mon, 11 Jan 2021 19:52:32 +0100 Subject: [PATCH 4/8] oops, these overloads are not here yet --- .../tests/FunctionalTests/SocketTestHelper.cs | 29 ------------------- 1 file changed, 29 deletions(-) diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SocketTestHelper.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SocketTestHelper.cs index 8f1c9a94d9ac40..93e050059ca719 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SocketTestHelper.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SocketTestHelper.cs @@ -460,35 +460,6 @@ public override async Task SendAsync(Socket s, ArraySegment buffer) return await s.SendAsync(m.Memory, SocketFlags.None).ConfigureAwait(false); } } - - public override async Task SendToAsync(Socket s, ArraySegment buffer, EndPoint endPoint) - { - using (var m = new NativeMemoryManager(buffer.Count)) - { - buffer.AsSpan().CopyTo(m.Memory.Span); - return await s.SendToAsync(m.Memory, SocketFlags.None, endPoint).ConfigureAwait(false); - } - } - - public override async Task ReceiveFromAsync(Socket s, ArraySegment buffer, EndPoint endPoint) - { - using (var m = new NativeMemoryManager(buffer.Count)) - { - SocketReceiveFromResult result = await s.ReceiveFromAsync(m.Memory, SocketFlags.None, endPoint).ConfigureAwait(false); - m.Memory.Span.Slice(0, result.ReceivedBytes).CopyTo(buffer.AsSpan()); - return result; - } - } - - public override async Task ReceiveMessageFromAsync(Socket s, ArraySegment buffer, EndPoint endPoint) - { - using (var m = new NativeMemoryManager(buffer.Count)) - { - SocketReceiveMessageFromResult result = await s.ReceiveMessageFromAsync(m.Memory, SocketFlags.None, endPoint).ConfigureAwait(false); - m.Memory.Span.Slice(0, result.ReceivedBytes).CopyTo(buffer.AsSpan()); - return result; - } - } } // From dd38c34f9de5e11628a232a3f93b5e857fef9b74 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Tue, 12 Jan 2021 15:00:39 +0100 Subject: [PATCH 5/8] ReceiveSentMessages_ReuseEventArgs_Success --- .../FunctionalTests/ReceiveMessageFrom.cs | 200 ++++-------------- .../ReceiveMessageFromAsync.cs | 76 ------- 2 files changed, 39 insertions(+), 237 deletions(-) diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/ReceiveMessageFrom.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/ReceiveMessageFrom.cs index 2c26edecb775bd..ed2d36686723cd 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/ReceiveMessageFrom.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/ReceiveMessageFrom.cs @@ -54,94 +54,43 @@ public async Task ReceiveSentMessages_Success(bool ipv4) } } - public class ReceiveMessageFrom_Old + public sealed class ReceiveMessageFrom_Sync : ReceiveMessageFrom { - [OuterLoop] - [Theory] - [InlineData(false)] - [InlineData(true)] - public void Success(bool forceNonBlocking) - { - if (Socket.OSSupportsIPv4) - { - using (Socket receiver = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)) - { - int port = receiver.BindToAnonymousPort(IPAddress.Loopback); - receiver.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.PacketInformation, true); - - receiver.ForceNonBlocking(forceNonBlocking); - - Socket sender = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); - sender.Bind(new IPEndPoint(IPAddress.Loopback, 0)); - - sender.ForceNonBlocking(forceNonBlocking); - - sender.SendTo(new byte[1024], new IPEndPoint(IPAddress.Loopback, port)); + public ReceiveMessageFrom_Sync(ITestOutputHelper output) : base(output) { } + } - IPPacketInformation packetInformation; - SocketFlags flags = SocketFlags.None; - EndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0); + public sealed class ReceiveMessageFrom_SyncForceNonBlocking : ReceiveMessageFrom + { + public ReceiveMessageFrom_SyncForceNonBlocking(ITestOutputHelper output) : base(output) { } + } - int len = receiver.ReceiveMessageFrom(new byte[1024], 0, 1024, ref flags, ref remoteEP, out packetInformation); + public sealed class ReceiveMessageFrom_Apm : ReceiveMessageFrom + { + public ReceiveMessageFrom_Apm(ITestOutputHelper output) : base(output) { } + } - Assert.Equal(1024, len); - Assert.Equal(sender.LocalEndPoint, remoteEP); - Assert.Equal(((IPEndPoint)sender.LocalEndPoint).Address, packetInformation.Address); + public sealed class ReceiveMessageFrom_Task : ReceiveMessageFrom + { + public ReceiveMessageFrom_Task(ITestOutputHelper output) : base(output) { } + } - sender.Dispose(); - } - } - } + public sealed class ReceiveMessageFrom_Eap : ReceiveMessageFrom + { + public ReceiveMessageFrom_Eap(ITestOutputHelper output) : base(output) { } - [OuterLoop] [Theory] [InlineData(false)] [InlineData(true)] - public void Success_IPv6(bool forceNonBlocking) + public void ReceiveSentMessages_ReuseEventArgs_Success(bool ipv4) { - if (Socket.OSSupportsIPv6) - { - using (Socket receiver = new Socket(AddressFamily.InterNetworkV6, SocketType.Dgram, ProtocolType.Udp)) - { - int port = receiver.BindToAnonymousPort(IPAddress.IPv6Loopback); - receiver.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.PacketInformation, true); - - receiver.ForceNonBlocking(forceNonBlocking); - - Socket sender = new Socket(AddressFamily.InterNetworkV6, SocketType.Dgram, ProtocolType.Udp); - sender.Bind(new IPEndPoint(IPAddress.IPv6Loopback, 0)); - - sender.ForceNonBlocking(forceNonBlocking); - - sender.SendTo(new byte[1024], new IPEndPoint(IPAddress.IPv6Loopback, port)); - - IPPacketInformation packetInformation; - SocketFlags flags = SocketFlags.None; - EndPoint remoteEP = new IPEndPoint(IPAddress.IPv6Any, 0); - - int len = receiver.ReceiveMessageFrom(new byte[1024], 0, 1024, ref flags, ref remoteEP, out packetInformation); - - Assert.Equal(1024, len); - Assert.Equal(sender.LocalEndPoint, remoteEP); - Assert.Equal(((IPEndPoint)sender.LocalEndPoint).Address, packetInformation.Address); + const int DatagramsToSend = 30; + const int TimeoutMs = 30_000; - sender.Dispose(); - } - } - } - - [OuterLoop] - [Theory] - [InlineData(false)] - [InlineData(true)] - public void Success_APM(bool ipv4) - { AddressFamily family; IPAddress loopback, any; SocketOptionLevel level; if (ipv4) { - if (!Socket.OSSupportsIPv4) return; family = AddressFamily.InterNetwork; loopback = IPAddress.Loopback; any = IPAddress.Any; @@ -149,86 +98,42 @@ public void Success_APM(bool ipv4) } else { - if (!Socket.OSSupportsIPv6) return; family = AddressFamily.InterNetworkV6; loopback = IPAddress.IPv6Loopback; any = IPAddress.IPv6Any; level = SocketOptionLevel.IPv6; } - using (var receiver = new Socket(family, SocketType.Dgram, ProtocolType.Udp)) - using (var sender = new Socket(family, SocketType.Dgram, ProtocolType.Udp)) - { - int port = receiver.BindToAnonymousPort(loopback); - receiver.SetSocketOption(level, SocketOptionName.PacketInformation, true); - sender.Bind(new IPEndPoint(loopback, 0)); - - sender.SendTo(new byte[1024], new IPEndPoint(loopback, port)); - - IPPacketInformation packetInformation; - SocketFlags flags = SocketFlags.None; - EndPoint remoteEP = new IPEndPoint(any, 0); + using var receiver = new Socket(family, SocketType.Dgram, ProtocolType.Udp); + using var sender = new Socket(family, SocketType.Dgram, ProtocolType.Udp); + using var saea = new SocketAsyncEventArgs(); + var completed = new ManualResetEventSlim(); + saea.Completed += delegate { completed.Set(); }; - IAsyncResult ar = receiver.BeginReceiveMessageFrom(new byte[1024], 0, 1024, flags, ref remoteEP, null, null); - int len = receiver.EndReceiveMessageFrom(ar, ref flags, ref remoteEP, out packetInformation); + int port = receiver.BindToAnonymousPort(loopback); + receiver.SetSocketOption(level, SocketOptionName.PacketInformation, true); + sender.Bind(new IPEndPoint(loopback, 0)); + saea.RemoteEndPoint = new IPEndPoint(any, 0); - Assert.Equal(1024, len); - Assert.Equal(sender.LocalEndPoint, remoteEP); - Assert.Equal(((IPEndPoint)sender.LocalEndPoint).Address, packetInformation.Address); - } - } - - [OuterLoop] - [Theory] - [InlineData(false, 0)] - [InlineData(false, 1)] - [InlineData(false, 2)] - [InlineData(true, 0)] - [InlineData(true, 1)] - [InlineData(true, 2)] - public void Success_EventArgs(bool ipv4, int bufferMode) - { - AddressFamily family; - IPAddress loopback, any; - SocketOptionLevel level; - if (ipv4) - { - if (!Socket.OSSupportsIPv4) return; - family = AddressFamily.InterNetwork; - loopback = IPAddress.Loopback; - any = IPAddress.Any; - level = SocketOptionLevel.IP; - } - else - { - if (!Socket.OSSupportsIPv6) return; - family = AddressFamily.InterNetworkV6; - loopback = IPAddress.IPv6Loopback; - any = IPAddress.IPv6Any; - level = SocketOptionLevel.IPv6; - } - - using (var receiver = new Socket(family, SocketType.Dgram, ProtocolType.Udp)) - using (var sender = new Socket(family, SocketType.Dgram, ProtocolType.Udp)) - using (var saea = new SocketAsyncEventArgs()) + for (int i = 0; i < DatagramsToSend; i++) { - int port = receiver.BindToAnonymousPort(loopback); - receiver.SetSocketOption(level, SocketOptionName.PacketInformation, true); - sender.Bind(new IPEndPoint(loopback, 0)); - - saea.RemoteEndPoint = new IPEndPoint(any, 0); + // apply bufferMode=0 two times, then bufferMode=1 two times etc. + int bufferMode = i / 2 % 3; switch (bufferMode) { case 0: // single buffer + saea.BufferList = null; saea.SetBuffer(new byte[1024], 0, 1024); break; case 1: // single buffer in buffer list + saea.SetBuffer(default); saea.BufferList = new List> { new ArraySegment(new byte[1024]) }; break; case 2: // multiple buffers in buffer list + saea.SetBuffer(default); saea.BufferList = new List> { new ArraySegment(new byte[512]), @@ -237,45 +142,18 @@ public void Success_EventArgs(bool ipv4, int bufferMode) break; } - var mres = new ManualResetEventSlim(); - saea.Completed += delegate { mres.Set(); }; - bool pending = receiver.ReceiveMessageFromAsync(saea); sender.SendTo(new byte[1024], new IPEndPoint(loopback, port)); - if (pending) Assert.True(mres.Wait(30000), "Expected operation to complete within timeout"); + if (pending) Assert.True(completed.Wait(TimeoutMs), "Expected operation to complete within timeout"); + completed.Reset(); Assert.Equal(1024, saea.BytesTransferred); Assert.Equal(sender.LocalEndPoint, saea.RemoteEndPoint); Assert.Equal(((IPEndPoint)sender.LocalEndPoint).Address, saea.ReceiveMessageFromPacketInfo.Address); - } + } } } - public sealed class ReceiveMessageFrom_Sync : ReceiveMessageFrom - { - public ReceiveMessageFrom_Sync(ITestOutputHelper output) : base(output) { } - } - - public sealed class ReceiveMessageFrom_SyncForceNonBlocking : ReceiveMessageFrom - { - public ReceiveMessageFrom_SyncForceNonBlocking(ITestOutputHelper output) : base(output) { } - } - - public sealed class ReceiveMessageFrom_Apm : ReceiveMessageFrom - { - public ReceiveMessageFrom_Apm(ITestOutputHelper output) : base(output) { } - } - - public sealed class ReceiveMessageFrom_Task : ReceiveMessageFrom - { - public ReceiveMessageFrom_Task(ITestOutputHelper output) : base(output) { } - } - - public sealed class ReceiveMessageFrom_Eap : ReceiveMessageFrom - { - public ReceiveMessageFrom_Eap(ITestOutputHelper output) : base(output) { } - } - public sealed class ReceiveMessageFrom_SpanSync : ReceiveMessageFrom { public ReceiveMessageFrom_SpanSync(ITestOutputHelper output) : base(output) { } diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/ReceiveMessageFromAsync.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/ReceiveMessageFromAsync.cs index d0e7131a920726..6b90a1795bbece 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/ReceiveMessageFromAsync.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/ReceiveMessageFromAsync.cs @@ -9,82 +9,6 @@ namespace System.Net.Sockets.Tests { public class ReceiveMessageFromAsync { - [OuterLoop] - [Theory] - [InlineData(false, false)] - [InlineData(false, true)] - [InlineData(true, false)] - [InlineData(true, true)] - public void ReceiveSentMessages_SocketAsyncEventArgs_Success(bool ipv4, bool changeReceiveBufferEachCall) - { - const int DataLength = 1024; - AddressFamily family = ipv4 ? AddressFamily.InterNetwork : AddressFamily.InterNetworkV6; - IPAddress loopback = ipv4 ? IPAddress.Loopback : IPAddress.IPv6Loopback; - var completed = new ManualResetEventSlim(false); - using (var sender = new Socket(family, SocketType.Dgram, ProtocolType.Udp)) - using (var receiver = new Socket(family, SocketType.Dgram, ProtocolType.Udp)) - { - sender.Bind(new IPEndPoint(loopback, 0)); - receiver.SetSocketOption(ipv4 ? SocketOptionLevel.IP : SocketOptionLevel.IPv6, SocketOptionName.PacketInformation, true); - int port = receiver.BindToAnonymousPort(loopback); - - var args = new SocketAsyncEventArgs() { RemoteEndPoint = new IPEndPoint(ipv4 ? IPAddress.Any : IPAddress.IPv6Any, 0) }; - args.Completed += (s,e) => completed.Set(); - args.SetBuffer(new byte[DataLength], 0, DataLength); - - for (int iters = 0; iters < 5; iters++) - { - sender.SendTo(new byte[DataLength], new IPEndPoint(loopback, port)); - - if (changeReceiveBufferEachCall) - { - args.SetBuffer(new byte[DataLength], 0, DataLength); - } - - if (!receiver.ReceiveMessageFromAsync(args)) - { - completed.Set(); - } - Assert.True(completed.Wait(TestSettings.PassingTestTimeout), "Timeout while waiting for connection"); - completed.Reset(); - - Assert.Equal(DataLength, args.BytesTransferred); - Assert.Equal(sender.LocalEndPoint, args.RemoteEndPoint); - Assert.Equal(((IPEndPoint)sender.LocalEndPoint).Address, args.ReceiveMessageFromPacketInfo.Address); - } - } - } - - [OuterLoop] - [Theory] - [InlineData(false)] - [InlineData(true)] - public async Task ReceiveSentMessages_Tasks_Success(bool ipv4) - { - const int DataLength = 1024; - AddressFamily family = ipv4 ? AddressFamily.InterNetwork : AddressFamily.InterNetworkV6; - IPAddress loopback = ipv4 ? IPAddress.Loopback : IPAddress.IPv6Loopback; - - using (var receiver = new Socket(family, SocketType.Dgram, ProtocolType.Udp)) - using (var sender = new Socket(family, SocketType.Dgram, ProtocolType.Udp)) - { - sender.Bind(new IPEndPoint(loopback, 0)); - receiver.SetSocketOption(ipv4 ? SocketOptionLevel.IP : SocketOptionLevel.IPv6, SocketOptionName.PacketInformation, true); - int port = receiver.BindToAnonymousPort(loopback); - - for (int iters = 0; iters < 5; iters++) - { - sender.SendTo(new byte[DataLength], new IPEndPoint(loopback, port)); - - SocketReceiveMessageFromResult result = await receiver.ReceiveMessageFromAsync( - new ArraySegment(new byte[DataLength], 0, DataLength), SocketFlags.None, - new IPEndPoint(ipv4 ? IPAddress.Any : IPAddress.IPv6Any, 0)); - Assert.Equal(DataLength, result.ReceivedBytes); - Assert.Equal(sender.LocalEndPoint, result.RemoteEndPoint); - Assert.Equal(((IPEndPoint)sender.LocalEndPoint).Address, result.PacketInformation.Address); - } - } - } } } From 748c798ef4c81dbca32c3ae85ec0074ce494f29f Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Tue, 12 Jan 2021 18:05:50 +0100 Subject: [PATCH 6/8] altering bufferMode does not work on Linux --- .../tests/FunctionalTests/ReceiveMessageFrom.cs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/ReceiveMessageFrom.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/ReceiveMessageFrom.cs index ed2d36686723cd..f342d11c7eed0c 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/ReceiveMessageFrom.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/ReceiveMessageFrom.cs @@ -79,9 +79,13 @@ public sealed class ReceiveMessageFrom_Eap : ReceiveMessageFrom public ReceiveMessageFrom_Eap(ITestOutputHelper output) : base(output) { } [Theory] - [InlineData(false)] - [InlineData(true)] - public void ReceiveSentMessages_ReuseEventArgs_Success(bool ipv4) + [InlineData(false, 0)] + [InlineData(false, 1)] + [InlineData(false, 2)] + [InlineData(true, 0)] + [InlineData(true, 1)] + [InlineData(true, 2)] + public void ReceiveSentMessages_ReuseEventArgs_Success(bool ipv4, int bufferMode) { const int DatagramsToSend = 30; const int TimeoutMs = 30_000; @@ -117,23 +121,18 @@ public void ReceiveSentMessages_ReuseEventArgs_Success(bool ipv4) for (int i = 0; i < DatagramsToSend; i++) { - // apply bufferMode=0 two times, then bufferMode=1 two times etc. - int bufferMode = i / 2 % 3; switch (bufferMode) { case 0: // single buffer - saea.BufferList = null; saea.SetBuffer(new byte[1024], 0, 1024); break; case 1: // single buffer in buffer list - saea.SetBuffer(default); saea.BufferList = new List> { new ArraySegment(new byte[1024]) }; break; case 2: // multiple buffers in buffer list - saea.SetBuffer(default); saea.BufferList = new List> { new ArraySegment(new byte[512]), From 10ae9ccfe725ea03bde7191c11d658892171c6a8 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Tue, 12 Jan 2021 18:13:17 +0100 Subject: [PATCH 7/8] remove ReceiveMessageFromAsync.cs --- .../FunctionalTests/ReceiveMessageFromAsync.cs | 14 -------------- .../System.Net.Sockets.Tests.csproj | 3 +-- 2 files changed, 1 insertion(+), 16 deletions(-) delete mode 100644 src/libraries/System.Net.Sockets/tests/FunctionalTests/ReceiveMessageFromAsync.cs diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/ReceiveMessageFromAsync.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/ReceiveMessageFromAsync.cs deleted file mode 100644 index 6b90a1795bbece..00000000000000 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/ReceiveMessageFromAsync.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Threading; -using System.Threading.Tasks; -using Xunit; - -namespace System.Net.Sockets.Tests -{ - public class ReceiveMessageFromAsync - { - - } -} diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/System.Net.Sockets.Tests.csproj b/src/libraries/System.Net.Sockets/tests/FunctionalTests/System.Net.Sockets.Tests.csproj index a7e0c5f6aa90df..7ce628db90aae5 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/System.Net.Sockets.Tests.csproj +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/System.Net.Sockets.Tests.csproj @@ -1,4 +1,4 @@ - + true true @@ -27,7 +27,6 @@ - From ba25fd56d86ca770e75b83295deecb8faf826eeb Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Tue, 12 Jan 2021 20:26:31 +0100 Subject: [PATCH 8/8] use AssertExtensions.SequenceEqual --- src/libraries/Common/tests/System/Net/Sockets/Fletcher32.cs | 2 -- .../tests/FunctionalTests/ReceiveMessageFrom.cs | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/Sockets/Fletcher32.cs b/src/libraries/Common/tests/System/Net/Sockets/Fletcher32.cs index 91d1c118813fe2..15451b84964056 100644 --- a/src/libraries/Common/tests/System/Net/Sockets/Fletcher32.cs +++ b/src/libraries/Common/tests/System/Net/Sockets/Fletcher32.cs @@ -61,7 +61,5 @@ public static uint Checksum(byte[] bytes, int offset, int count) fletcher32.Add(bytes, offset, count); return fletcher32.Sum; } - - public static uint Checksum(byte[] bytes) => Checksum(bytes, 0, bytes.Length); } } diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/ReceiveMessageFrom.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/ReceiveMessageFrom.cs index f342d11c7eed0c..6bc70e67a7fa87 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/ReceiveMessageFrom.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/ReceiveMessageFrom.cs @@ -47,7 +47,7 @@ public async Task ReceiveSentMessages_Success(bool ipv4) IPPacketInformation packetInformation = result.PacketInformation; Assert.Equal(DatagramSize, result.ReceivedBytes); - Assert.Equal(Fletcher32.Checksum(sendBuffer), Fletcher32.Checksum(receiveBuffer)); + AssertExtensions.SequenceEqual(sendBuffer, receiveBuffer); Assert.Equal(sender.LocalEndPoint, result.RemoteEndPoint); Assert.Equal(((IPEndPoint)sender.LocalEndPoint).Address, packetInformation.Address); }