@Test
  public void testLocalAddressReuse() throws Exception {

    for (int i = 0; i < 2; i++) {
      LocalAddress addr = new LocalAddress(LOCAL_ADDR_ID);
      Bootstrap cb = new Bootstrap();
      ServerBootstrap sb = new ServerBootstrap();

      cb.eventLoop(new LocalEventLoop())
          .channel(new LocalChannel())
          .remoteAddress(addr)
          .handler(new TestHandler());

      sb.eventLoop(new LocalEventLoop(), new LocalEventLoop())
          .channel(new LocalServerChannel())
          .localAddress(addr)
          .childHandler(
              new ChannelInitializer<LocalChannel>() {
                @Override
                public void initChannel(LocalChannel ch) throws Exception {
                  ch.pipeline().addLast(new TestHandler());
                }
              });

      // Start server
      Channel sc = sb.bind().sync().channel();

      // Connect to the server
      Channel cc = cb.connect().sync().channel();

      // Send a message event up the pipeline.
      cc.pipeline().inboundMessageBuffer().add("Hello, World");
      cc.pipeline().fireInboundBufferUpdated();

      // Close the channel
      cc.close().sync();

      sb.shutdown();
      cb.shutdown();

      sc.closeFuture().sync();

      Assert.assertTrue(
          String.format(
              "Expected null, got channel '%s' for local address '%s'",
              LocalChannelRegistry.get(addr), addr),
          LocalChannelRegistry.get(addr) == null);
    }
  }
Esempio n. 2
0
    @Override
    public void connect(
        final SocketAddress remoteAddress,
        SocketAddress localAddress,
        final ChannelPromise promise) {
      if (!promise.setUncancellable() || !ensureOpen(promise)) {
        return;
      }

      if (state == State.CONNECTED) {
        Exception cause = new AlreadyConnectedException();
        safeSetFailure(promise, cause);
        pipeline().fireExceptionCaught(cause);
        return;
      }

      if (connectPromise != null) {
        throw new ConnectionPendingException();
      }

      connectPromise = promise;

      if (state != State.BOUND) {
        // Not bound yet and no localAddress specified - get one.
        if (localAddress == null) {
          localAddress = new LocalAddress(LocalChannel.this);
        }
      }

      if (localAddress != null) {
        try {
          doBind(localAddress);
        } catch (Throwable t) {
          safeSetFailure(promise, t);
          close(voidPromise());
          return;
        }
      }

      Channel boundChannel = LocalChannelRegistry.get(remoteAddress);
      if (!(boundChannel instanceof LocalServerChannel)) {
        Exception cause = new ChannelException("connection refused");
        safeSetFailure(promise, cause);
        close(voidPromise());
        return;
      }

      LocalServerChannel serverChannel = (LocalServerChannel) boundChannel;
      peer = serverChannel.serve(LocalChannel.this);
    }
Esempio n. 3
0
    @Override
    public void connect(
        final SocketAddress remoteAddress, SocketAddress localAddress, final ChannelFuture future) {
      if (eventLoop().inEventLoop()) {
        if (!ensureOpen(future)) {
          return;
        }

        if (state == 2) {
          Exception cause = new AlreadyConnectedException();
          future.setFailure(cause);
          pipeline().fireExceptionCaught(cause);
          return;
        }

        if (connectFuture != null) {
          throw new ConnectionPendingException();
        }

        connectFuture = future;

        if (state != 1) {
          // Not bound yet and no localAddress specified - get one.
          if (localAddress == null) {
            localAddress = new LocalAddress(LocalChannel.this);
          }
        }

        if (localAddress != null) {
          try {
            doBind(localAddress);
          } catch (Throwable t) {
            future.setFailure(t);
            pipeline().fireExceptionCaught(t);
            close(voidFuture());
            return;
          }
        }

        Channel boundChannel = LocalChannelRegistry.get(remoteAddress);
        if (!(boundChannel instanceof LocalServerChannel)) {
          Exception cause = new ChannelException("connection refused");
          future.setFailure(cause);
          pipeline().fireExceptionCaught(cause);
          close(voidFuture());
          return;
        }

        LocalServerChannel serverChannel = (LocalServerChannel) boundChannel;
        peer = serverChannel.serve(LocalChannel.this);
      } else {
        final SocketAddress localAddress0 = localAddress;
        eventLoop()
            .execute(
                new Runnable() {
                  @Override
                  public void run() {
                    connect(remoteAddress, localAddress0, future);
                  }
                });
      }
    }