如何以正确的方式关闭套接字? [英] How can I close the socket in a proper way?

查看:57
本文介绍了如何以正确的方式关闭套接字?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

This is a simple TCP server. How can i close the socket when the program is terminated? I have using try/finally and try to close the socket. But it doesn't run the finally block when I exit the program.

任何人都知道如何以正确的方式关闭套接字?

Anyone can have idea on how to close the socket in a proper way?

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!");
    }

推荐答案

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

After creating your ServerSocket, you could add a ShutdownHook to close it on JVM termination, something like this:

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 仍然会终止,但有点乱.

Invoking ServerSocket#close will terminate the blocking ServerSocket.accept call, causing it to throw a SocketException. However, note that your current handling of IOException in the while loop means you will then re-enter the while loop to attempt accept on a closed socket. The JVM will still terminate, but it's a bit untidy.

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

Shutdown hooks do not run if you terminate a console application in Eclipse (on Windows at least). But they do run if you CTRL-C Java in a normal console. For them to run, you need the JVM to be terminated normally, e.g. SIGINT or SIGTERM rather than SIGKILL (kill -9).

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

A simple program which you can execute in Eclipse or a console will demonstrate this.

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

这篇关于如何以正确的方式关闭套接字?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆