Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java-无异常关闭ServerSocket?_Java_Multithreading_Exception_Connection_Serversocket - Fatal编程技术网

Java-无异常关闭ServerSocket?

Java-无异常关闭ServerSocket?,java,multithreading,exception,connection,serversocket,Java,Multithreading,Exception,Connection,Serversocket,多年来,我一直在想,在Java中关闭监听服务器套接字的正确方法是什么。我的实现总是这样工作,它们: 创建一个新的ServerSocket(int) 启动在while(true)循环中调用其accept()方法的线程 当accept()返回(客户端连接)时启动另一个线程,从客户端读取数据,直到断开连接。然后,accept线程继续执行另一个accept()调用 但是当我想关闭ServerSocket,因为我的应用程序正在退出时,除了调用它的close()方法(在我关闭了所有客户端套接字之后),我再也

多年来,我一直在想,在Java中关闭监听服务器套接字的正确方法是什么。我的实现总是这样工作,它们:

  • 创建一个新的ServerSocket(int)
  • 启动在while(true)循环中调用其accept()方法的线程
  • 当accept()返回(客户端连接)时启动另一个线程,从客户端读取数据,直到断开连接。然后,accept线程继续执行另一个accept()调用
  • 但是当我想关闭ServerSocket,因为我的应用程序正在退出时,除了调用它的close()方法(在我关闭了所有客户端套接字之后),我再也找不到其他方法来关闭它,这会导致accept()抛出SocketException,我捕获它并在accept线程中中断while(true)循环,导致所有线程退出

    我觉得这很难看,严格来说没有例外,关闭我的ServerSocket是我程序正常运行的一部分

    是否真的没有其他方法可以在不引发异常的情况下执行此操作

    谢谢

    除了调用它的close()方法(在我关闭了所有客户端套接字之后),我还没有找到其他方法来执行此操作

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

    这会导致accept()抛出SocketException

    SocketClosedException是此处的预期行为

    我捕捉到它并在accept线程中中断while(true)循环

    如果你在循环之外捕捉到它,你不需要也打破循环。如果引发异常,并且您已设置
    closed=true
    ,则可以放弃该异常

    顺便说一句,我会的

    while(!serverSocket.isClosed()) {
    
    导致所有线程退出

    没有什么特别的理由需要这样做,但是如果你愿意,你可以选择这样做

    我觉得这很难看,严格来说也不例外

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

    关闭服务器套接字是程序正常操作的一部分


    或者,您可以说它在运行时运行正常,没有关闭。

    谢谢您的评论

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

    打开新插座以关闭现有插座?在我看来,这是有史以来最严重的罪过之一

    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设置为true,则可以放弃该异常

    顺便说一句,我会的

    而(!serverSocket.isClosed()){

    这是可行的,但我认为这应该在不设置标志和捕获异常的情况下工作

    异常情况正在发生。没有发生的是错误

    或者,您可以说它在运行时运行正常,没有关闭

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

    为什么在调用close()时accept()方法不直接返回null呢?那会容易得多。

    似乎没有办法:可能是