如何以正确的方式关闭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函数。