Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I close the socket in a proper way? [duplicate]

Tags:

java

tcp

sockets

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!");
    }
like image 229
TheOneTeam Avatar asked Nov 08 '11 14:11

TheOneTeam


2 Answers

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

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.

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).

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");
  }
}
like image 53
sudocode Avatar answered Sep 28 '22 04:09

sudocode


No need in your particular case, the operating system will close all the TCP sockets for you when the program exits.

like image 25
artbristol Avatar answered Sep 28 '22 03:09

artbristol