ServerSocket 不会等到关闭后再打开

ServerSocket wont wait until it's closed to reopen

我正在 java 中编写一个 client/server 应用程序,我试图让服务器能够自行重启。当前,服务器接受连接,从客户端读取对象,然后将 Object/Socket/Stream 传递给从那里接管的新线程。下一部分是问题所在:要重新启动已经 运行ning 服务器(我们称此实例为 "instance 1"),我启动了它的一个新实例(实例 2)。如果 ServerSocket 已经在使用中,实例 2 应该向 ServerSocket 写入一个空值,这将导致实例 1 关闭它,然后实例 2 应该只是 运行 与以前相同的块。这样做成功地终止了实例 1,但除非我进入调试模式并控制哪一行发生,否则实例 2 会在关闭之前尝试重新打开 ServerSocket,因此它也会终止。我无法让实例 2 等到 ServerSocket 关闭后再尝试打开它。有没有我找不到的方法或实现?

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

尝试在延时循环中打开 ServerSocket,例如

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

使用线程将是处理此问题的合适方法。如果你想使用线程,那么你可以按照我的例子。

    public static void main(String[] args) {            
        renderServer(9000);//render socket and handle request
    }

    public static void renderServer(int port){    
        ServerSocket  serverSocket  = new ServerSocket (port);
        System.out.println("Server started on "+ new Date());     

        while(true){
            Socket socket = serverSocket.accept(); 

            HandleClient handleClient = new HandleClient(socket);
            Thread thread = new Thread(handleClient);
            thread.start();
        }
    }

然后您必须创建 HandleClient class 来处理每个请求。请注意 HandleClient class 必须实现 Runnable,如下例所示。

public class HandleClient implements Runnable{ 

        Socket socket;

        public HandleClient(Socket socket){
            this.socket = socket;
        }


        @Override
        public void run() {
            //Your code goes in here
            DataInputStream in = new DataInputStream(socket.getInputStream());
            DataOutputStream out = new DataOutputStream(socket.getOutputStream());
            //Then you can continue from here
        }

}