private void ReceiveMessageFrom_Helper(IPAddress listenOn, IPAddress connectTo, bool expectedToTimeout = false)
{
using (Socket serverSocket = new Socket(SocketType.Dgram, ProtocolType.Udp))
{
int port = serverSocket.BindToAnonymousPort(listenOn);
EndPoint receivedFrom = new IPEndPoint(connectTo, port);
SocketFlags socketFlags = SocketFlags.None;
IPPacketInformation ipPacketInformation;
int received = 0;
serverSocket.ReceiveTimeout = TestSettings.FailingTestTimeout;
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
Assert.Throws<SocketException>(() =>
{
// This is a false start.
// http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.receivemessagefrom.aspx
// "...the returned IPPacketInformation object will only be valid for packets which arrive at the
// local computer after the socket option has been set. If a socket is sent packets between when
// it is bound to a local endpoint (explicitly by the Bind method or implicitly by one of the Connect,
// ConnectAsync, SendTo, or SendToAsync methods) and its first call to the ReceiveMessageFrom method,
// calls to ReceiveMessageFrom method will return invalid IPPacketInformation objects for these packets."
received = serverSocket.ReceiveMessageFrom(new byte[1], 0, 1, ref socketFlags, ref receivedFrom, out ipPacketInformation);
});
}
else
{
// *nix may throw either a SocketException or ArgumentException in this case, depending on how the IP stack
// behaves w.r.t. dual-mode sockets bound to IPv6-specific addresses.
Assert.ThrowsAny<Exception>(() =>
{
received = serverSocket.ReceiveMessageFrom(new byte[1], 0, 1, ref socketFlags, ref receivedFrom, out ipPacketInformation);
});
}
serverSocket.ReceiveTimeout = expectedToTimeout ? TestSettings.FailingTestTimeout : TestSettings.PassingTestTimeout;
SocketUdpClient client = new SocketUdpClient(_log, serverSocket, connectTo, port);
receivedFrom = new IPEndPoint(connectTo, port);
socketFlags = SocketFlags.None;
received = serverSocket.ReceiveMessageFrom(new byte[1], 0, 1, ref socketFlags, ref receivedFrom, out ipPacketInformation);
Assert.Equal(1, received);
Assert.Equal<Type>(receivedFrom.GetType(), typeof(IPEndPoint));
IPEndPoint remoteEndPoint = receivedFrom as IPEndPoint;
Assert.Equal(AddressFamily.InterNetworkV6, remoteEndPoint.AddressFamily);
Assert.Equal(connectTo.MapToIPv6(), remoteEndPoint.Address);
Assert.Equal(SocketFlags.None, socketFlags);
Assert.NotNull(ipPacketInformation);
Assert.Equal(connectTo, ipPacketInformation.Address);
}
}