예제 #1
0
  public void testAcceptor() throws Exception {
    threadFactory.clear();
    log.info("Test: testAcceptor");
    final CountDownLatch ioLatch = new CountDownLatch(4);
    final CountDownLatch closeLatch = new CountDownLatch(2);
    final AtomicBoolean clientOpened = new AtomicBoolean();
    final AtomicBoolean clientReadOnceOK = new AtomicBoolean();
    final AtomicBoolean clientReadDoneOK = new AtomicBoolean();
    final AtomicBoolean clientReadTooMuch = new AtomicBoolean();
    final AtomicBoolean clientWriteOK = new AtomicBoolean();
    final AtomicBoolean serverOpened = new AtomicBoolean();
    final AtomicBoolean serverReadOnceOK = new AtomicBoolean();
    final AtomicBoolean serverReadDoneOK = new AtomicBoolean();
    final AtomicBoolean serverReadTooMuch = new AtomicBoolean();
    final AtomicBoolean serverWriteOK = new AtomicBoolean();
    final byte[] bytes = "Ummagumma!".getBytes("UTF-8");
    final Xnio xnio = Xnio.getInstance("nio");
    final ReadChannelThread readChannelThread = xnio.createReadChannelThread(threadFactory);
    final ReadChannelThread clientReadChannelThread = xnio.createReadChannelThread(threadFactory);
    final WriteChannelThread writeChannelThread = xnio.createWriteChannelThread(threadFactory);
    final WriteChannelThread clientWriteChannelThread =
        xnio.createWriteChannelThread(threadFactory);
    final ConnectionChannelThread connectionChannelThread =
        xnio.createConnectionChannelThread(threadFactory);
    try {
      final FutureResult<InetSocketAddress> futureAddressResult =
          new FutureResult<InetSocketAddress>();
      final IoFuture<InetSocketAddress> futureAddress = futureAddressResult.getIoFuture();
      final IoFuture<? extends ConnectedStreamChannel> futureConnection =
          xnio.acceptStream(
              new InetSocketAddress(Inet4Address.getByAddress(new byte[] {127, 0, 0, 1}), 0),
              connectionChannelThread,
              clientReadChannelThread,
              clientWriteChannelThread,
              new ChannelListener<ConnectedStreamChannel>() {
                private final ByteBuffer inboundBuf = ByteBuffer.allocate(512);
                private int readCnt = 0;
                private final ByteBuffer outboundBuf = ByteBuffer.wrap(bytes);

                public void handleEvent(final ConnectedStreamChannel channel) {
                  channel
                      .getCloseSetter()
                      .set(
                          new ChannelListener<ConnectedStreamChannel>() {
                            public void handleEvent(final ConnectedStreamChannel channel) {
                              closeLatch.countDown();
                            }
                          });
                  channel
                      .getReadSetter()
                      .set(
                          new ChannelListener<ConnectedStreamChannel>() {
                            public void handleEvent(final ConnectedStreamChannel channel) {
                              try {
                                final int res = channel.read(inboundBuf);
                                if (res == 0) {
                                  channel.resumeReads();
                                } else if (res == -1) {
                                  serverReadDoneOK.set(true);
                                  ioLatch.countDown();
                                  channel.shutdownReads();
                                } else {
                                  final int ttl = readCnt += res;
                                  if (ttl == bytes.length) {
                                    serverReadOnceOK.set(true);
                                  } else if (ttl > bytes.length) {
                                    serverReadTooMuch.set(true);
                                    IoUtils.safeClose(channel);
                                    return;
                                  }
                                  channel.resumeReads();
                                }
                              } catch (IOException e) {
                                log.errorf(e, "Server read failed");
                                IoUtils.safeClose(channel);
                              }
                            }
                          });
                  channel
                      .getWriteSetter()
                      .set(
                          new ChannelListener<ConnectedStreamChannel>() {
                            public void handleEvent(final ConnectedStreamChannel channel) {
                              try {
                                channel.write(outboundBuf);
                                if (!outboundBuf.hasRemaining()) {
                                  serverWriteOK.set(true);
                                  Channels.shutdownWritesBlocking(channel);
                                  ioLatch.countDown();
                                }
                              } catch (IOException e) {
                                log.errorf(e, "Server write failed");
                                IoUtils.safeClose(channel);
                              }
                            }
                          });
                  channel.resumeReads();
                  channel.resumeWrites();
                  serverOpened.set(true);
                }
              },
              new ChannelListener<BoundChannel>() {
                public void handleEvent(final BoundChannel channel) {
                  futureAddressResult.setResult(channel.getLocalAddress(InetSocketAddress.class));
                }
              },
              OptionMap.create(Options.REUSE_ADDRESSES, Boolean.TRUE));
      final InetSocketAddress localAddress = futureAddress.get();
      final IoFuture<? extends ConnectedStreamChannel> ioFuture =
          xnio.connectStream(
              localAddress,
              connectionChannelThread,
              readChannelThread,
              writeChannelThread,
              new ChannelListener<ConnectedStreamChannel>() {
                private final ByteBuffer inboundBuf = ByteBuffer.allocate(512);
                private int readCnt = 0;
                private final ByteBuffer outboundBuf = ByteBuffer.wrap(bytes);

                public void handleEvent(final ConnectedStreamChannel channel) {
                  channel
                      .getCloseSetter()
                      .set(
                          new ChannelListener<ConnectedStreamChannel>() {
                            public void handleEvent(final ConnectedStreamChannel channel) {
                              closeLatch.countDown();
                            }
                          });
                  channel
                      .getReadSetter()
                      .set(
                          new ChannelListener<ConnectedStreamChannel>() {
                            public void handleEvent(final ConnectedStreamChannel channel) {
                              try {
                                final int res = channel.read(inboundBuf);
                                if (res == 0) {
                                  channel.resumeReads();
                                } else if (res == -1) {
                                  channel.shutdownReads();
                                  clientReadDoneOK.set(true);
                                  ioLatch.countDown();
                                } else {
                                  final int ttl = readCnt += res;
                                  if (ttl == bytes.length) {
                                    clientReadOnceOK.set(true);
                                  } else if (ttl > bytes.length) {
                                    clientReadTooMuch.set(true);
                                    IoUtils.safeClose(channel);
                                    return;
                                  }
                                  channel.resumeReads();
                                }
                              } catch (IOException e) {
                                log.errorf(e, "Client read failed");
                                IoUtils.safeClose(channel);
                              }
                            }
                          });
                  channel
                      .getWriteSetter()
                      .set(
                          new ChannelListener<ConnectedStreamChannel>() {
                            public void handleEvent(final ConnectedStreamChannel channel) {
                              try {
                                channel.write(outboundBuf);
                                if (!outboundBuf.hasRemaining()) {
                                  clientWriteOK.set(true);
                                  Channels.shutdownWritesBlocking(channel);
                                  ioLatch.countDown();
                                }
                              } catch (IOException e) {
                                log.errorf(e, "Client write failed");
                                IoUtils.safeClose(channel);
                              }
                            }
                          });
                  channel.resumeReads();
                  channel.resumeWrites();
                  clientOpened.set(true);
                }
              },
              null,
              OptionMap.EMPTY);
      assertTrue("Read timed out", ioLatch.await(500L, TimeUnit.MILLISECONDS));
      assertTrue("Close timed out", closeLatch.await(500L, TimeUnit.MILLISECONDS));
      assertFalse("Client read too much", clientReadTooMuch.get());
      assertTrue("Client read OK", clientReadOnceOK.get());
      assertTrue("Client read done", clientReadDoneOK.get());
      assertTrue("Client write OK", clientWriteOK.get());
      assertFalse("Server read too much", serverReadTooMuch.get());
      assertTrue("Server read OK", serverReadOnceOK.get());
      assertTrue("Server read done", serverReadDoneOK.get());
      assertTrue("Server write OK", serverWriteOK.get());
    } finally {
      readChannelThread.shutdown();
      writeChannelThread.shutdown();
      clientReadChannelThread.shutdown();
      clientWriteChannelThread.shutdown();
      connectionChannelThread.shutdown();
    }
    threadFactory.await();
  }
예제 #2
0
 private void doConnectionTest(
     final Runnable body,
     final ChannelListener<? super ConnectedStreamChannel> clientHandler,
     final ChannelListener<? super ConnectedStreamChannel> serverHandler)
     throws Exception {
   Xnio xnio = Xnio.getInstance("nio", NioTcpTestCase.class.getClassLoader());
   final ConnectionChannelThread connectionChannelThread =
       xnio.createConnectionChannelThread(threadFactory);
   final ConnectionChannelThread serverChannelThread =
       xnio.createConnectionChannelThread(threadFactory);
   final ReadChannelThread readChannelThread = xnio.createReadChannelThread(threadFactory);
   final ReadChannelThread clientReadChannelThread = xnio.createReadChannelThread(threadFactory);
   final WriteChannelThread writeChannelThread = xnio.createWriteChannelThread(threadFactory);
   final WriteChannelThread clientWriteChannelThread =
       xnio.createWriteChannelThread(threadFactory);
   try {
     final AcceptingChannel<? extends ConnectedStreamChannel> server =
         xnio.createStreamServer(
             new InetSocketAddress(
                 Inet4Address.getByAddress(new byte[] {127, 0, 0, 1}), SERVER_PORT),
             serverChannelThread,
             ChannelListeners.<ConnectedStreamChannel>openListenerAdapter(
                 readChannelThread,
                 writeChannelThread,
                 new CatchingChannelListener<ConnectedStreamChannel>(
                     serverHandler, threadFactory)),
             OptionMap.create(Options.REUSE_ADDRESSES, Boolean.TRUE));
     server.resumeAccepts();
     try {
       final IoFuture<? extends ConnectedStreamChannel> ioFuture =
           xnio.connectStream(
               new InetSocketAddress(
                   Inet4Address.getByAddress(new byte[] {127, 0, 0, 1}), SERVER_PORT),
               connectionChannelThread,
               clientReadChannelThread,
               clientWriteChannelThread,
               new CatchingChannelListener<ConnectedStreamChannel>(clientHandler, threadFactory),
               null,
               OptionMap.EMPTY);
       final ConnectedStreamChannel channel = ioFuture.get();
       try {
         body.run();
         channel.close();
         server.close();
       } catch (Exception e) {
         log.errorf(e, "Error running body");
         throw e;
       } catch (Error e) {
         log.errorf(e, "Error running body");
         throw e;
       } finally {
         IoUtils.safeClose(channel);
       }
     } finally {
       IoUtils.safeClose(server);
     }
   } finally {
     connectionChannelThread.shutdown();
     serverChannelThread.shutdown();
     clientReadChannelThread.shutdown();
     clientWriteChannelThread.shutdown();
     readChannelThread.shutdown();
     writeChannelThread.shutdown();
   }
   connectionChannelThread.awaitTermination();
   serverChannelThread.awaitTermination();
   readChannelThread.awaitTermination();
   writeChannelThread.awaitTermination();
   clientReadChannelThread.awaitTermination();
   clientWriteChannelThread.awaitTermination();
 }