问题描述
这是一个简单的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后,你可以添加在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 */ }
}});
调用将终止阻塞调用,导致它抛出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");
}
}
这篇关于如何以正确的方式关闭插座?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!