多年来,我一直想知道在Java中关闭监听ServerSocket的正确方法是什么。我的实现总是这样,他们:
但是当我想要关闭ServerSocket因为我的应用程序正在退出时,除了调用它的close()方法(在我关闭所有客户端套接字之后)之外,我从未找到另一种方法,这会导致接受( )抛出一个SocketException,我抓住它并从接受线程中的while(true)循环中断,导致我的所有线程退出。
我认为这很难看,严格来说没有发生异常,关闭我的ServerSocket是我程序正常运行的一部分。
在没有引起异常抛出的情况下,真的没有其他办法吗?
感谢。
答案 0 :(得分:1)
除了调用它的close()方法(在我关闭所有客户端套接字后)之外,我从未找到另一种方法,
您可以设置标志closed = true;
并打开虚拟连接以唤醒在继续之前检查该标志的accept()线程。
导致accept()抛出SocketException,
SocketClosedException,这是预期的行为。
我抓住了它,并从接受线程中的while(true)循环中断开,
如果你在循环之外捕获它,你也不需要打破循环。如果抛出异常并且您已设置closed = true
,则可以放弃该异常。
顺便说一下,我会这样做
while(!serverSocket.isClosed()) {
导致我的所有线程退出。
您没有特别需要这样做,但如果您愿意,可以选择这样做。
我认为这很难看,严格来说没有例外,
正在发生异常情况。没有发生的是错误。
关闭我的ServerSocket是我程序正常运行的一部分。
或者你可以说当它正在运行而没有关机时它正常运行。
答案 1 :(得分:0)
感谢您的评论。
你可以设置一个标志关闭=真;并打开一个虚拟连接来唤醒在继续之前检查该标志的accept()线程。
打开一个新的Socket以关闭现有的Socket?国际海事组织是有史以来最严重的罪行之一。
SocketClosedException,这是预期的行为。
实际上它不会抛出SocketClosedException而是抛出SocketException,代码如下:
try {
final ServerSocket ss = new ServerSocket(1234);
new Thread(new Runnable() {
@Override
public void run() {
try {
ss.accept();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}).start();
ss.close();
} catch (Exception ex) {
ex.printStackTrace();
}
产生以下输出:
java.net.SocketException: Socket is closed
at java.net.ServerSocket.accept(ServerSocket.java:494)
at Main$1.run(Main.java:12)
at java.lang.Thread.run(Thread.java:744)
如果你在循环之外捕获它,你也不需要打破循环。如果抛出异常并且您设置了closed = true,则可以放弃该异常。
顺便说一下,我会这样做
while(!serverSocket.isClosed()){
这样可行,但我认为这应该可以在不设置标记和捕获异常的情况下工作。
正在发生异常情况。没有发生的是错误。
或者你可以说当它正在运行而没有关机时它正常运行。
我不同意。应用程序退出是正常行为。他们可能总是这样做。
为什么accept()方法在调用close()时才返回null?那会更容易。