我正在用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();
}
}
}
答案 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
}
}