首页 文章

Java - 关闭没有例外的ServerSocket?

提问于
浏览
3

多年来我一直想知道在Java中关闭监听ServerSocket的正确方法是什么 . 我的实现总是这样工作,他们:

  • 创建一个新的ServerSocket(int) .

  • 启动一个在while(true)循环中调用其accept()方法的线程 .

  • 当accept()返回(客户端连接)从客户端读取直到断开连接时,启动另一个线程 . 接受线程然后继续另一个accept()调用 .

但是当我想要关闭ServerSocket因为我的应用程序正在退出时,除了调用它的close()方法(在我关闭所有客户端套接字之后)之外我从未找到另一种方法,这会导致accept()抛出一个SocketException,我 grab 它并从接受线程中的while(true)循环中断,导致我的所有线程都退出 .

我认为这很难看,严格来说没有异常发生,关闭我的ServerSocket是我程序正常运行的一部分 .

在没有引发异常的情况下,真的没有其他办法吗?

谢谢 .

2 回答

  • 0

    谢谢你的评论 .

    你可以设置一个标志关闭=真;并打开一个虚拟连接来唤醒在继续之前检查该标志的accept()线程 .

    打开一个新的Socket以关闭现有的Socket? IMO是有史以来最严重的罪行之一 .

    一个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,则可以放弃该异常 . 顺便说一下,我会这样做(!serverSocket.isClosed()){

    这可行,但我认为这应该没有设置标志和捕获例外 .

    一种特殊情况正在发生 . 没有发生的是错误 . 或者你可以说它正在运行而没有关机时正常运行 .

    我不同意 . 应用程序退出是正常行为 . 他们可能总是这样做 .

    为什么在调用close()时accept()方法只返回null?那会更容易 .

  • 1

    除了调用它的close()方法(在我关闭所有客户端套接字之后),我从未发现过这样做的另一种方式,

    您可以设置一个标志 closed = true; 并打开一个虚拟连接来唤醒在继续之前检查该标志的accept()线程 .

    导致accept()抛出SocketException,

    一个SocketClosedException,这是预期的行为 .

    我 grab 了那个并从接受线程中的while(true)循环中断开,

    如果你在循环之外捕获它,你也不需要打破循环 . 如果抛出异常并且您已设置 closed = true ,则可以放弃该异常 .

    顺便说一下,我会这样做

    while(!serverSocket.isClosed()) {
    

    导致我的所有线程退出 .

    您没有特别需要这样做,但如果您愿意,可以选择这样做 .

    我认为这很难看,严格来说没有例外,

    一种特殊情况正在发生 . 没有发生的是错误 .

    关闭我的ServerSocket是我程序正常运行的一部分 .

    或者你可以说它正在运行而没有关机时正常运行 .

相关问题