如何以正确的方式关闭sockets?

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

任何人都可以知道如何以正确的方式关闭sockets?

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终止时关闭它,如下所示:

 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或控制台中执行的简单程序将certificate这一点。

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

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

来自javadoc :

Java运行时自动关闭输入和输出流,客户端套接字和服务器套接字,因为它们是在try-with-resources语句中创建的。

在程序退出之前,Java虚拟机( JVM )会调用finalize()方法,以使程序有机会清理和释放资源。 multithreading程序应该在退出之前关闭它们使用的所有文件和套接字,这样它们就不会面临资源匮乏。 finalize()方法中对server.close()的调用将关闭此程序中每个线程使用的Socket连接。

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

怎么终于没有运行? 也许应该用像这样的东西替换while(true)

 while (!shutdownRequested) 

或者你可以创建一个处理套接字关闭的关闭钩子

那么,你如何“退出”该计划? 如果抛出exception或者try块以“正常”方式完成执行, finally将被执行,但我认为由于你的while(true)可能会“很难”。

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