【问题标题】:Is it possible to see if a client is trying to connect a ServerSocket?是否可以查看客户端是否正在尝试连接 ServerSocket?
【发布时间】:2021-02-11 20:24:58
【问题描述】:

我有这个循环在一个线程中运行:

ServerSocket ss = new ServerSocket(PORT);
while (running) {
    ClientHandler ch = new ClientHandler(ss.accept);
}

它保持ServerSocket 运行等待连接。我想要做的是有一个 if 语句来检查是否有客户端尝试连接,如果没有,它将再次运行 while 语句。这将使停止线程运行更容易。目前,我只是在代码的不同部分有一个System.exit(0) 来停止程序。那么有没有办法只接受一个等待接受的客户端,否则它会测试它是否还需要运行?

【问题讨论】:

    标签: java while-loop server


    【解决方案1】:

    是否可以查看客户端是否正在尝试连接ServerSocket

    是的,这是可能的,但不一定是可取的。

    您需要使用ServerSocketChannelSelector。您创建通道并将其绑定到端口,然后将其注册到选择器。然后查看是否有传入连接,在选择器上调用selectNow() 以测试通道是否准备好。

    https://www.baeldung.com/java-nio-selector 有一个示例:参见第 8.1 节。 (请注意,该示例使用select() 而不是selectNow()。这会阻塞线程......这不是您想要的。)


    如果您真的只是想在监听器循环被阻塞时停止它,还有其他一些选择:

    1. 您的控制线程可以在发出accept() 调用的Thread 上调用interrupt()accept 应该抛出 InterruptedIOException。为了完整起见,while 还应该测试线程的中断标志。

    2. 我认为另一个线程也可以在ServerSocket 上调用close()。如果一个线程当前在 accept() 调用中被阻塞,它应该得到一个异常。

    注意:我没有亲自尝试过这两种方法,所以我不能保证它们会奏效。但两者都比使用SelectorselectNow()轮询 更简单(并且可能更好)的解决方案。

    调用System.exit 也不是一个糟糕的解决方案,IMO。

    【讨论】:

    • 我个人更喜欢 Thread.interrupt 方法,但我也看到 ss.setSoTimeout 到 1000ms 或 100ms 这样的短时间,吞下 SocketTimeoutException,然后循环进行测试
    • 是的。这与轮询 selectNow 有类似的缺点
    猜你喜欢
    • 1970-01-01
    • 2015-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多