【发布时间】:2016-07-26 15:33:09
【问题描述】:
我正在用 java 编写客户端/服务器应用程序,并且我正在尝试使服务器能够自行重新启动。目前,服务器接受一个连接,从客户端读取一个对象,然后将对象/套接字/流传递给一个新的线程,该线程从那里接管。下一部分是问题所在:要重新启动已经运行的服务器(让我们将此实例称为“实例 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();
}
}
}
【问题讨论】:
-
你需要学习多线程的概念,它有助于实现你想要的。此外,您想要实现的目标也不清楚。
-
没错,但我很确定我至少知道这部分。我的问题是我找不到任何 ServerSockets 实现,它可以让我在实例 2 打开之前安全地等待实例 1 关闭 ServerSocket。我想要实现的是能够只打开服务器的另一个实例(此处为测试器),它将关闭前一个实例,然后像旧实例一样接管端口。最终我将添加实现以优雅地关闭 ServerSocket,这样我们就不需要在每次想要重新启动服务器时断开所有客户端。
-
那你将如何更新你的服务器?我们需要能够在不杀死前一个线程的情况下即时更新服务器。线程可能需要几个小时,所以我们不能只告诉客户端上的用户停止使用服务器,直到线程完成。该解决方案将让服务器的实例 1 完成其旧线程,并让新的和改进的实例 2 处理新的
标签: java sockets serversocket