释放在Java中的一个监听ServerSocket。

4

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

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

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

现在我该怎么做?


这似乎足够相关 - gtgaxiola
1
你不能使用 interrupt() 来杀死线程。accept() 方法是不可中断的。只需关闭套接字即可。你会收到一个异常,你必须接受它。 - user207421
@EJP 这是一个有趣的事实,也是真实的。虽然文档没有提到,但是如果线程正在等待可中断操作(例如使用ServerSocket进行监听),*interrupt()将不起作用*。线程状态仍然为Thread.State.RUNNABLE - MC Emperor
@MCEmperor 事实往往是真实的,无论它们是否有趣,但 ServerSocket.accept() 不是可中断的操作。只有 InterruptibleChannels 具有可中断的操作,但它们并没有太大用处,因为中断会关闭通道,这是由于 Linux 的一种特殊性质必须传播到所有平台。 - user207421
@EJP 是的,我看到了我的错误:"正在等待可中断操作"必须改为"正在等待不可中断操作"。 - MC Emperor
2个回答

4

我不会杀死/中断ServerSocket正在监听的线程。只需在其他线程中调用ServerSocket的close方法即可。


这个答案是正确的方法。确保其他线程可以访问ServerSocket变量并关闭它。 - Necreaux

0

正如EJP所说,accept()方法是不可中断的,因此我试图杀死的ConnListener线程无法被杀死,而interrupt()没有效果。

相反,我必须由StartStopSwitch线程关闭ServerSocket,从而引发SocketException。似乎没有办法整洁地关闭套接字并避免抛出异常。

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();
}

请参考这篇Stackoverflow帖子以获取更多细节。


@user207421 我花了4年半的时间。;-) - MC Emperor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接