ServerSocket不会等到它关闭才能重新打开

时间:2016-07-26 15:33:10

标签: java sockets serversocket

我正在用java编写客户端/服务器应用程序,我正在尝试让服务器能够重启自己。目前,服务器接受连接,从客户端读取Object,然后将Object / Socket / Stream传递给从那里接管的新Thread。下一部分是问题:要重新启动已经运行的服务器(让我们调用此实例“实例1”),我启动它的新实例(实例2)。如果ServerSocket已经在使用中,则实例2应该向ServerSocket写入一个null,这将导致实例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();
        }
    }
}

2 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

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

    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类。请注意,HandleClient类必须实现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
        }

}