场景:一个程序启动一个服务器并监听另一个程序连接到该服务器;如果另一个程序连接,则终止旧程序上的服务器并在新程序上启动同一服务器,然后重复该循环。
第一次运行程序后,我得到:
thread started
attempting connection
server started
然后,再次运行程序后,第一个实例显示为:
thread started
attempting connection
server started
Another instance was started, this instance has been shut down
Exception in thread "Thread-0" java.lang.NullPointerException
at me.aj.phoenix.util.JustOneServer.startServer(JustOneServer.java:37)
at me.aj.phoenix.util.JustOneServer.run(JustOneServer.java:28)
第二个例子是:
attempting connection
Another instance was running and has been closed.
server started
java.net.BindException: Address already in use: NET_Bind
at java.base/java.net.PlainSocketImpl.bind0(Native Method)
at java.base/java.net.PlainSocketImpl.socketBind(PlainSocketImpl.java:132)
at java.base/java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:436)
at java.base/java.net.ServerSocket.bind(ServerSocket.java:381)
at java.base/java.net.ServerSocket.<init>(ServerSocket.java:243)
at java.base/java.net.ServerSocket.<init>(ServerSocket.java:187)
at me.aj.phoenix.util.JustOneServer.startServer(JustOneServer.java:34)
at me.aj.phoenix.util.JustOneServer.run(JustOneServer.java:26)
基本上我想做的是每当启动新版本的程序时,关闭旧程序并在新程序上启动监听器
代码如下:
public class TestProgram extends Thread {
public final int port = 9665;
ServerSocket serverSocket = null;
Socket clientSocket = null;
@Override
public void run() {
System.out.println("thread started");
try {
this.check();
this.startServer();
} catch (IOException ioe) {
this.startServer();
}
}
public void startServer() {
try {
System.out.println("server started");
serverSocket = new ServerSocket(port, 1);
clientSocket = serverSocket.accept();
Logger.print("Another instance was started, this instance has been shut down");
System.exit(0);
} catch (IOException e) {
e.printStackTrace();
}
}
public void check() throws UnknownHostException, IOException {
System.out.println("attempting connection");
Socket socket = new Socket("localhost", port);
if(socket.isConnected()) {
Logger.print("Another instance was running and has been closed.");
}
}
}
第二个程序没有等待第一个程序监听服务器与端口解除绑定(bind),我不太确定如何修复它。
最佳答案
主要问题是 startServer
方法中的逻辑应该在无限循环中运行,以解决可能随时断开连接的套接字的弱性,更重要的是对于以下场景正在尝试连接到由前一个正在关闭的实例绑定(bind)的端口。
while (true)
runServer(port);
其他问题包括在出现问题时关闭资源以及嵌套来自客户端 Socket
的异常与来自 ServerSocket
的异常;因此,每当为 ServerSocket
抛出异常时,都不会被解释为结束 startServer
方法执行的异常。
void runServer(int port) {
try (ServerSocket serverSocket = new ServerSocket(port, 1)) {
logger.debug("Server started!");
try (Socket clientSocket = serverSocket.accept()) {
logger.debug("Signal to shutdown received. Shutting down.");
System.exit(0);
}
} catch (IOException e) {
logger.debug("The other application is still shutting down...");
}
}
下面是一个完整的工作示例:
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ServerReplacer {
private static Logger logger = LoggerFactory.getLogger(ServerReplacer.class);
public static void runReplacerService(int port) {
searchOlderInstances(port);
logger.debug("Server starting...");
while (true)
runServer(port);
}
private static void searchOlderInstances(int port) {
logger.debug("Attempting to find older instance...");
try (Socket socket = new Socket("127.0.0.1", port)) {
logOtherInstanceFound(socket.isConnected());
} catch (Exception e) {
logOtherInstanceFound(false);
}
}
private static void logOtherInstanceFound(boolean otherInstanceFound) {
logger.debug(otherInstanceFound ?
"FOUND ANOTHER INSTANCE RUNNING! It has been signaled to shut down." :
"No older instance found.");
}
private static void runServer(int port) {
try (ServerSocket serverSocket = new ServerSocket(port, 1)) {
logger.debug("Server started!");
try (Socket clientSocket = serverSocket.accept()) {
logger.debug("Signal to shutdown received. Shutting down.");
System.exit(0);
}
} catch (IOException e) {
logger.debug("The other application is still shutting down...");
}
}
public static void main(String[] args) {
runReplacerService(9665);
}
}
希望这对您有所帮助。
关于java - 如果启动了较新的实例,则终止程序的较旧实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56242731/