Search code examples
javasocketsserversocket

ServerSocket wont wait until it's closed to reopen


I am writing a client/server app in java, and I am trying to make the server capable of restarting itself. Currently, the server accepts a connection, reads an Object from the client, then passes the Object/Socket/Stream to a new Thread which takes over from there. This next part is the problem though: to restart the already running server (lets call this instance "instance 1"), I start a new instance of it (instance 2). If the ServerSocket is already in use, instance 2 should write a null to the ServerSocket which will cause instance 1 to close it, then instance 2 should just run the same block as before. Doing this successfully terminates instance 1, but unless I enter debug mode and control which line happens when, instance 2 tries to reopen the ServerSocket before it is closed, so it terminates as well. I cannot get instance 2 to wait until the ServerSocket is closed to try opening it again. Is there a method or implementation for this I just can't find?

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Tester {

    protected ExecutorService threadPool = Executors.newFixedThreadPool(10);

    public static void main(String[] args) {
        new Tester();
    }

    public Tester () {
        try {
            listen();
        } catch (Exception e) {
            try {
                Socket socket = new Socket("127.0.0.1", 4444);
                new ObjectOutputStream(socket.getOutputStream()).writeObject(null);
                socket.close();

                listen();
            } catch (Exception ex) { e.printStackTrace(); }
        }

        return;
    }

    public void listen () throws Exception {
        try (ServerSocket serverSocket = new ServerSocket(4444);) {
            while (true) {
                Socket clientSocket = serverSocket.accept();
                ObjectInputStream in = new ObjectInputStream(clientSocket.getInputStream());
                Object obj = in.readObject();
                if(obj == null)
                    break;
          //    this.threadPool.execute(new ServerThread( ... ));
            }
            threadPool.shutdown();
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception();
        }
    }
}

Solution

  • Try opening the ServerSocket in a time-delayed loop, like

    for (int i = 0; i < 3; i++) {
      Thread.sleep(2000); //select your sleep time
      try {
        reopenMyServerSocket();
        break;
      }
      catch (IOException iox) {}
    }