【问题标题】:ServerSocketChannel.socket() is still bound after close()ServerSocketChannel.socket() 在 close() 之后仍然绑定
【发布时间】:2019-12-03 11:05:06
【问题描述】:

我使用 java.nio 进行服务器编程,它工作正常。 当我尝试关闭套接字时:

    serverChannel.socket().close();

        serverChannel.close();  

    boolean b1 = serverChannel.socket().isBound();   
  boolean b2 =
     serverChannel.socket().isClosed();

并检查值,b1 为真,b2 为真。 当我运行 netstat 时,我看到状态 od 端口是“LISTENNING” 当我使用“旧” IO 时,关闭套接字完全符合我的预期(netstat 没有将端口列为监听)。

如何在不关闭 JVM 的情况下“解除绑定”套接字?

【问题讨论】:

  • isBound() 仅表示您直接或间接致电bind()。它永远不会再变成假的。这并不意味着底层端口仍在使用中。除非你用Selector 来解决这里没有问题,在这种情况下关闭直到下一次选择操作才会生效。你可以用selectNow()强制它。
  • NB 你不需要两个都关闭。任何一个都足够了。
  • @user207421 "这里没有问题可以解决,除非您将它与选择器一起使用,在这种情况下,关闭直到下一次选择操作才会生效。您可以使用 selectNow( )" 我正在使用选择器,但我无法获得它。你有任何链接或参考。
  • 对我来说似乎非常清楚。请参阅 Javadoc。

标签: java socketchannel


【解决方案1】:

我找到了解决方案。我们必须记住,keys 也包含 serverSocketChannel。

if(this.serverChannel != null && this.serverChannel.isOpen()) {

    try {

        this.serverChannel.close();

    } catch (IOException e) {

        log.error("Exception while closing server socket");
    }
}

try {

    Iterator<SelectionKey> keys = this.selector.keys().iterator();

    while(keys.hasNext()) {

        SelectionKey key = keys.next();

        SelectableChannel channel = key.channel();

        if(channel instanceof SocketChannel) {

            SocketChannel socketChannel = (SocketChannel) channel;
            Socket socket = socketChannel.socket();
            String remoteHost = socket.getRemoteSocketAddress().toString();

            log.info("closing socket {}", remoteHost);

            try {

                socketChannel.close();

            } catch (IOException e) {

                log.warn("Exception while closing socket", e);
            }

            key.cancel();
        }
    }

    log.info("closing selector");
    selector.close();

} catch(Exception ex) {

    log.error("Exception while closing selector", ex);
}

Does Selector.close() closes all client sockets?

【讨论】:

  • 这里没有任何内容可以解决您在问题中陈述的 LISTENING 问题,并且在关闭服务器套接字时关闭所有客户端套接字是不必要的中止。当你尝试shutdownNow() 时发生了什么?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多