public void SimpleSend(IByteBuffer source, bool bindClient, IByteBufferAllocator allocator, AddressFamily addressFamily, byte[] expectedData, int count) { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { return; } SocketDatagramChannel serverChannel = null; IChannel clientChannel = null; var serverGroup = new MultithreadEventLoopGroup(1); var clientGroup = new MultithreadEventLoopGroup(1); try { var handler = new TestHandler(expectedData); var serverBootstrap = new Bootstrap(); serverBootstrap .Group(serverGroup) .ChannelFactory(() => new SocketDatagramChannel(addressFamily)) .Option(ChannelOption.Allocator, allocator) .Option(ChannelOption.SoBroadcast, true) .Option(ChannelOption.IpMulticastLoopDisabled, false) .Handler(new ActionChannelInitializer <IChannel>(channel => { channel.Pipeline.AddLast(nameof(SocketDatagramChannelUnicastTest), handler); })); IPAddress address = NetUtil.GetLoopbackAddress(addressFamily); this.Output.WriteLine($"Unicast server binding to:({addressFamily}){address}"); Task <IChannel> task = serverBootstrap.BindAsync(address, IPEndPoint.MinPort); Assert.True(task.Wait(TimeSpan.FromMilliseconds(DefaultTimeOutInMilliseconds * 5)), $"Unicast server binding to:({addressFamily}){address} timed out!"); serverChannel = (SocketDatagramChannel)task.Result; var endPoint = (IPEndPoint)serverChannel.LocalAddress; var clientBootstrap = new Bootstrap(); clientBootstrap .Group(clientGroup) .ChannelFactory(() => new SocketDatagramChannel(addressFamily)) .Option(ChannelOption.Allocator, allocator) .Option(ChannelOption.SoBroadcast, true) .Option(ChannelOption.IpMulticastLoopDisabled, false) .Handler(new ActionChannelInitializer <IChannel>(channel => { channel.Pipeline.AddLast("Dummy", new NetUtil.DummyHandler()); })); var clientEndPoint = new IPEndPoint( addressFamily == AddressFamily.InterNetwork ? IPAddress.Any : IPAddress.IPv6Any, IPEndPoint.MinPort); clientBootstrap .LocalAddress(clientEndPoint) .RemoteAddress(new IPEndPoint(address, endPoint.Port)); if (bindClient) { this.Output.WriteLine($"Unicast client binding to:({addressFamily}){address}"); task = clientBootstrap.BindAsync(clientEndPoint); Assert.True(task.Wait(TimeSpan.FromMilliseconds(DefaultTimeOutInMilliseconds * 5)), $"Unicast client binding to:({clientEndPoint}) timed out!"); clientChannel = task.Result; } else { this.Output.WriteLine($"Register client binding to:({addressFamily}){address}"); task = (Task <IChannel>)clientBootstrap.RegisterAsync(); Assert.True(task.Wait(TimeSpan.FromMilliseconds(DefaultTimeOutInMilliseconds)), "Unicast client register timed out!"); clientChannel = task.Result; } for (int i = 0; i < count; i++) { var packet = new DatagramPacket((IByteBuffer)source.Retain(), new IPEndPoint(address, endPoint.Port)); clientChannel.WriteAndFlushAsync(packet).Wait(); Assert.True(handler.WaitForResult()); var duplicatedPacket = (DatagramPacket)packet.Duplicate(); duplicatedPacket.Retain(); clientChannel.WriteAndFlushAsync(duplicatedPacket).Wait(); Assert.True(handler.WaitForResult()); } } finally { serverChannel?.CloseAsync().Wait(TimeSpan.FromMilliseconds(DefaultTimeOutInMilliseconds)); clientChannel?.CloseAsync().Wait(TimeSpan.FromMilliseconds(DefaultTimeOutInMilliseconds)); source.Release(); Task.WaitAll( serverGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(5)), clientGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(5))); } }
public void Multicast(AddressFamily addressFamily, IByteBufferAllocator allocator) { SocketDatagramChannel serverChannel = null; IChannel clientChannel = null; var serverGroup = new MultithreadEventLoopGroup(1); var clientGroup = new MultithreadEventLoopGroup(1); NetworkInterface loopback = NetUtil.LoopbackInterface(addressFamily); try { var multicastHandler = new MulticastTestHandler(); var serverBootstrap = new Bootstrap(); serverBootstrap .Group(serverGroup) .ChannelFactory(() => new SocketDatagramChannel(addressFamily)) .Option(ChannelOption.Allocator, allocator) .Option(ChannelOption.SoReuseaddr, true) .Option(ChannelOption.IpMulticastLoopDisabled, false) .Handler(new ActionChannelInitializer <IChannel>(channel => { channel.Pipeline.AddLast(nameof(SocketDatagramChannelMulticastTest), multicastHandler); })); IPAddress address = addressFamily == AddressFamily.InterNetwork ? IPAddress.Loopback : IPAddress.IPv6Loopback; this.Output.WriteLine($"Multicast server binding to:({addressFamily}){address}"); Task <IChannel> task = serverBootstrap.BindAsync(address, IPEndPoint.MinPort); Assert.True(task.Wait(TimeSpan.FromMilliseconds(DefaultTimeOutInMilliseconds * 5)), $"Multicast server binding to:({addressFamily}){address} timed out!"); serverChannel = (SocketDatagramChannel)task.Result; var serverEndPoint = (IPEndPoint)serverChannel.LocalAddress; var clientBootstrap = new Bootstrap(); clientBootstrap .Group(clientGroup) .ChannelFactory(() => new SocketDatagramChannel(addressFamily)) .Option(ChannelOption.Allocator, allocator) .Option(ChannelOption.SoReuseaddr, true) .Option(ChannelOption.IpMulticastLoopDisabled, false) .Handler(new ActionChannelInitializer <IChannel>(channel => { channel.Pipeline.AddLast("Dummy", new NetUtil.DummyHandler()); })); this.Output.WriteLine($"Multicast client binding to:({addressFamily}){address}"); task = clientBootstrap.BindAsync(address, IPEndPoint.MinPort); Assert.True(task.Wait(TimeSpan.FromMilliseconds(DefaultTimeOutInMilliseconds * 5)), $"Multicast client binding to:({addressFamily}){address} timed out!"); clientChannel = (SocketDatagramChannel)task.Result; IPAddress multicastAddress = addressFamily == AddressFamily.InterNetwork ? IPAddress.Parse("230.0.0.1") : IPAddress.Parse("ff12::1"); var groupAddress = new IPEndPoint(multicastAddress, serverEndPoint.Port); Task joinTask = serverChannel.JoinGroup(groupAddress, loopback); Assert.True(joinTask.Wait(TimeSpan.FromMilliseconds(DefaultTimeOutInMilliseconds * 5)), $"Multicast server join group {groupAddress} timed out!"); clientChannel.WriteAndFlushAsync(new DatagramPacket(Unpooled.Buffer().WriteInt(1), groupAddress)).Wait(); Assert.True(multicastHandler.WaitForResult(), "Multicast server should have receivied the message."); Task leaveTask = serverChannel.LeaveGroup(groupAddress, loopback); Assert.True(leaveTask.Wait(TimeSpan.FromMilliseconds(DefaultTimeOutInMilliseconds * 5)), $"Multicast server leave group {groupAddress} timed out!"); // sleep half a second to make sure we left the group Task.Delay(DefaultTimeOutInMilliseconds).Wait(); // we should not receive a message anymore as we left the group before clientChannel.WriteAndFlushAsync(new DatagramPacket(Unpooled.Buffer().WriteInt(1), groupAddress)).Wait(); Assert.False(multicastHandler.WaitForResult(), "Multicast server should not receive the message."); } finally { serverChannel?.CloseAsync().Wait(TimeSpan.FromMilliseconds(DefaultTimeOutInMilliseconds)); clientChannel?.CloseAsync().Wait(TimeSpan.FromMilliseconds(DefaultTimeOutInMilliseconds)); Task.WaitAll( serverGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1)), clientGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1))); } }