有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何以正确的方式关闭socket?

这是一个简单的TCP服务器。程序终止时,如何关闭socket? 我使用try/finally并尝试关闭socket。但当我退出程序时,它不会运行finally块

任何人都知道如何正确关闭插座

try {
        socket = new ServerSocket(port);
        System.out.println("Server is starting on port " + port + " ...");
    }catch (IOException e){
        System.out.println("Error on socket creation!");
    }

    Socket connectionSocket = null;
    try{
        while(true){            
            try{
                connectionSocket = socket.accept();
                Thread t =  new Thread(new ClientConnection(connectionSocket));
                t.start();
            }catch (IOException e) {
                System.out.println("Error on accept socket!");
            }
        }
    }finally{
        this.socket.close();
        System.out.println("The server is shut down!");
    }

共 (5) 个答案

  1. # 1 楼答案

    那么,如何“退出”该计划^如果抛出异常或try块以“正常”方式完成其执行,则将执行{},但我认为这可能“困难”,因为您的{}

    要关闭套接字,您应该使用socket.close(),我建议您不要依赖destroy函数

  2. # 2 楼答案

    为什么最后不跑?可能while(true)应该替换为

    while (!shutdownRequested)
    

    或者,您可以创建一个关闭钩子来处理套接字关闭

  3. # 3 楼答案

    javadoc

    The Java runtime automatically closes the input and output streams, the client socket, and the server socket because they have been created in the try-with-resources statement.

    The finalize() method is called by the Java virtual machine (JVM) before the program exits to give the program a chance to clean up and release resources. Multi-threaded programs should close all Files and Sockets they use before exiting so they do not face resource starvation. The call to server.close() in the finalize() method closes the Socket connection used by each thread in this program.

    protected void finalize(){
    //Objects created in run method are finalized when
    //program terminates and thread exits
         try{
            server.close();
        } catch (IOException e) {
            System.out.println("Could not close socket");
            System.exit(-1);
        }
      }
    
  4. # 4 楼答案

    创建ServerSocket后,可以添加一个ShutdownHook在JVM终止时关闭它,如下所示:

    Runtime.getRuntime().addShutdownHook(new Thread(){public void run(){
        try {
            socket.close();
            System.out.println("The server is shut down!");
        } catch (IOException e) { /* failed */ }
    }});
    

    调用ServerSocket#close将终止阻塞ServerSocket.accept调用,导致它抛出SocketException。但是,请注意,您当前在while循环中对IOException的处理意味着您将重新进入while循环以尝试在闭合套接字上接受。JVM仍将终止,但它有点不整洁

    如果在Eclipse中终止控制台应用程序(至少在Windows上),则关闭挂钩不会运行。但如果在普通控制台中使用CTRL-C Java,它们确实会运行。要让它们运行,需要JVM正常终止,例如SIGINT或SIGTERM,而不是SIGKILL(kill-9)

    您可以在Eclipse或控制台中执行的一个简单程序将演示这一点

    public class Test implements Runnable {
    
      public static void main(String[] args) throws InterruptedException {
        final Test test = new Test();
        Runtime.getRuntime().addShutdownHook(new Thread(){public void run(){
          test.shutdown();
        }});
        Thread t = new Thread(test);
        t.start();
      }
    
      public void run() {
        synchronized(this) {
          try {
            System.err.println("running");
            wait();
          } catch (InterruptedException e) {}
        }
      }
    
      public void shutdown() {
        System.err.println("shutdown");
      }
    }
    
  5. # 5 楼答案

    无需在您的特定情况下,当程序退出时,操作系统将为您关闭所有TCP套接字