public void TcpSocketChannel_Flush_should_not_be_reentrant_after_Close() { // Skip for Mono due to Code Contracts assertions not working properly there if (MonotonicClock.IsMono) return; var eventLoopGroup = new MultithreadEventLoopGroup(1); try { var futures = new ConcurrentQueue<Task>(); var sb = new ServerBootstrap(); sb.Group(eventLoopGroup).Channel<TcpServerSocketChannel>().ChildOption(ChannelOption.SoSndbuf, 1024) .ChildHandler(new ChannelFlushCloseHandler(futures)); var address = (IPEndPoint) sb.BindAsync(IPAddress.IPv6Loopback, 0).Result.LocalAddress; var s = new System.Net.Sockets.Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp); s.Connect(address.Address, address.Port); var inputStream = new NetworkStream(s, true); var buf = new byte[8192]; while (true) { var readBytes = inputStream.Read(buf, 0, 8192); if (readBytes == 0) { break; } // Wait a little bit so that the write attempts are split into multiple flush attempts. Thread.Sleep(10); } s.Close(); Assert.Equal(3, futures.Count); Task future1, future2, future3; futures.TryDequeue(out future1); futures.TryDequeue(out future2); futures.TryDequeue(out future3); Assert.True(future1.IsCompleted); Assert.False(future1.IsFaulted || future1.IsCanceled); Assert.True(future2.IsFaulted || future2.IsCanceled); Assert.IsType<ClosedChannelException>(future2.Exception.InnerException); Assert.True(future3.IsFaulted || future3.IsCanceled); Assert.IsType<ClosedChannelException>(future3.Exception.InnerException); } finally { eventLoopGroup.ShutdownGracefullyAsync(); } }
public void TcpSocketChannel_can_connect_to_TcpServerSocketChannel() { IEventLoopGroup group1 = new MultithreadEventLoopGroup(2); IEventLoopGroup group2 = new MultithreadEventLoopGroup(2); var cb = new ClientBootstrap(); var sb = new ServerBootstrap(); var reads = 100; var resetEvent = new ManualResetEventSlim(); cb.Group(group1) .Channel<TcpSocketChannel>() .Handler( new ActionChannelInitializer<TcpSocketChannel>( channel => { channel.Pipeline.AddLast(new LengthFieldBasedFrameDecoder(20, 0, 4, 0, 4)) .AddLast(new LengthFieldPrepender(4, false)) .AddLast(new IntCodec()) .AddLast(new TestHandler()); })); sb.Group(group2) .Channel<TcpServerSocketChannel>() .ChildHandler( new ActionChannelInitializer<TcpSocketChannel>( channel => { channel.Pipeline.AddLast(new LengthFieldBasedFrameDecoder(20, 0, 4, 0, 4)) .AddLast(new LengthFieldPrepender(4, false)) .AddLast(new IntCodec()) .AddLast(new ReadCountAwaiter(resetEvent, reads)) .AddLast(new TestHandler()); })); IChannel sc = null; IChannel cc = null; try { // Start server sc = sb.BindAsync(TEST_ADDRESS).Result; // Connect to the server cc = cb.ConnectAsync(sc.LocalAddress).Result; foreach (var read in Enumerable.Range(0, reads)) { cc.WriteAndFlushAsync(read); } Assert.True(resetEvent.Wait(15000)); } finally { CloseChannel(cc); CloseChannel(sc); Task.WaitAll(group1.ShutdownGracefullyAsync(), group2.ShutdownGracefullyAsync()); } }