【问题标题】:'Release' a listening ServerSocket in Java在 Java 中“释放”一个监听 ServerSocket
【发布时间】:2019-10-04 15:11:54
【问题描述】:

我有一个线程(假设它叫做ConnListener),它通过ServerSocketaccept() 方法监听传入的连接。

在另一个线程(称为 StartStopSwitch)中,我希望停止监听线程,并且不再监听给定的地址和端口。

我可以使用Thread.interrupt() 杀死线程,但是当我通过netstat 命令检查使用的端口时,我仍然看到状态为“LISTENING”的端口。我想在不抛出异常的情况下“释放”(或“解除绑定”)ServerSocket,因此在使用netstat 时不会显示。

现在我该怎么做?

【问题讨论】:

  • 你不能杀死 interrupt(). 的线程 accept() 方法是不可中断的。只需关闭套接字。你会得到一个例外,你只需要忍受它。
  • @EJP 这是一个有趣的事实,也是事实。尽管the docs 没有提及它,但如果线程正在等待可中断的操作,例如使用ServerSocket 进行侦听,interrupt() 将不起作用。线程状态依然是Thread.State.RUNNABLE
  • @MCEmperor 事实往往是真实的,无论是否有趣,但ServerSocket.accept() 不是一个可中断的操作。只有InterruptibleChannels 具有可中断操作,但它们并没有多大用处,因为中断关闭了通道,这是由于必须传播到所有平台的 Linux 特性。
  • @EJP 是的,我看到我犯了一个错误:“正在等待可中断操作”必须是“正在等待-可中断操作”。跨度>

标签: java sockets


【解决方案1】:

我不会杀死/中断 ServerSocket 正在侦听的线程。只需从另一个线程调用 ServerSocket 上的 close 即可。

【讨论】:

  • 这个答案是要走的路。确保其他线程可以访问 ServerSocket 变量并关闭它。
【解决方案2】:

正如EJP 所说,accept() 方法是不可中断的,所以我试图杀死的 ConnListener 线程无法被杀死,而@987654324 @ 无效。

相反,我不得不通过 StartStopSwitch 线程关闭 ServerSocket,导致抛出 SocketException。好像没有办法整齐的关闭socket,避免抛出异常。

try {
    Socket socket = serverSocket.accept();
}
catch (SocketException exc) {
    // SocketException is thrown when serverSocket is closed.
}
finally {
    // You don't have to close the socket, because in order to
    // reach this block, another thread had to close the socket.

    //serverSocket.close();
}

更多详情请见this Stackoverflow post

【讨论】:

  • @user207421 我花了 4½ 年。 ;-)
猜你喜欢
  • 2019-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-26
  • 1970-01-01
  • 1970-01-01
  • 2021-03-13
  • 1970-01-01
相关资源
最近更新 更多