@Test
    public void testConnection6() throws Throwable {
        final LoopHandle loop = new LoopHandle();
        if (!UDPHandleTest.isIPv6Enabled(loop)) {
            return;
        }

        final AtomicInteger serverSendCount = new AtomicInteger(0);
        final AtomicInteger clientSendCount = new AtomicInteger(0);

        final AtomicInteger serverRecvCount = new AtomicInteger(0);
        final AtomicInteger clientRecvCount = new AtomicInteger(0);

        final AtomicBoolean serverDone = new AtomicBoolean(false);
        final AtomicBoolean clientDone = new AtomicBoolean(false);

        final TCPHandle server = new TCPHandle(loop);
        final TCPHandle peer = new TCPHandle(loop);
        final TCPHandle client = new TCPHandle(loop);

        final Logger serverLoggingCallback = new Logger("s: ");
        final Logger clientLoggingCallback = new Logger("c: ");

        final Random random = new Random();

        server.setConnectionCallback(new StreamConnectionCallback() {
            @Override
            public void onConnection(int status, Exception error) throws Exception {
                serverLoggingCallback.log(status, error);
                server.accept(peer);
                peer.readStart();
                System.out.println("s: " + server.getSocketName() + " connected to " + peer.getPeerName());
                peer.write("message " + serverSendCount.getAndIncrement() + " from server");
                server.close(); // not expecting any more connections
            }
        });

        peer.setReadCallback(new StreamReadCallback() {
            @Override
            public void onRead(final ByteBuffer data) throws Exception {
                serverRecvCount.incrementAndGet();
                if (data == null) {
                    peer.close();
                } else {
                    final Object[] args = {data};
                    serverLoggingCallback.log(args);
                    if (serverRecvCount.get() == TIMES) {
                        peer.close();
                    } else {
                        peer.write("message " + serverSendCount.getAndIncrement() + " from server");
                    }
                }
            }
        });

        peer.setCloseCallback(new StreamCloseCallback() {
            @Override
            public void onClose() throws Exception { // close
                serverDone.set(true);
            }
        });

        client.setReadCallback(new StreamReadCallback() {
            @Override
            public void onRead(final ByteBuffer data) throws Exception {
                clientRecvCount.incrementAndGet();
                if (data == null) {
                    client.close();
                } else {
                    final Object[] args = {data};
                    clientLoggingCallback.log(args);
                    if (clientRecvCount.get() == TIMES) {
                        client.close();
                    } else {
                        client.write("message " + clientSendCount.getAndIncrement() + " from client");
                    }
                }
            }
        });

        client.setConnectCallback(new StreamConnectCallback() {
            @Override
            public void onConnect(int status, Exception error) throws Exception {
                clientLoggingCallback.log(status, error);
                System.out.println("c: " + client.getSocketName() + " connected to " + client.getPeerName());
                client.readStart();
                client.write("message " + clientSendCount.getAndIncrement() + " from client");
            }
        });

        client.setCloseCallback(new StreamCloseCallback() {
            @Override
            public void onClose() throws Exception { // close
                clientDone.set(true);
            }
        });

        server.bind6(ADDRESS6, PORT6);
        server.listen(1);

        Thread.sleep((long) (random.nextDouble() * 100));
        client.connect6(ADDRESS6, PORT6);

        while (!serverDone.get() || !clientDone.get()) {
            loop.run();
        }

        Assert.assertEquals(serverSendCount.get(), TIMES);
        Assert.assertEquals(clientSendCount.get(), TIMES);
        Assert.assertEquals(serverRecvCount.get(), TIMES);
        Assert.assertEquals(clientRecvCount.get(), TIMES);
    }