我正在尝试编写基于套接字的聊天应用程序,但我有点困惑,如何真正停止我的服务器。
这是我的Server
构造函数
public Server(int port) {
this.port = port;
this.shutdown = false;
this.clientComponentSet = new HashSet<>();
LOGGER.info("Starting the server...\n");
dbConnection = new DBConnection();
dbConnection.establish();
if(dbConnection.isConnected()) {
LOGGER.info("Established connection with database\n");
} else {
LOGGER.warn("Can't establish connection with database\n");
}
machineString = new SimpleStringProperty();
addressString = new SimpleStringProperty();
portString = new SimpleStringProperty();
status = new SimpleStringProperty();
status.set("Offline");
}
然后进入run
方法
@Override
public void run() {
try {
serverSocket = new ServerSocket(port);
Platform.runLater(
() -> {
try {
machineString.set(serverSocket.getInetAddress().getLocalHost().getHostName());
addressString.set(serverSocket.getInetAddress().getLocalHost().getHostAddress());
} catch (UnknownHostException e) {
LOGGER.error(e.toString());
}
portString.set(String.valueOf(this.port));
status.set("Online");
}
);
LOGGER.info("Server started\n");
while(!serverSocket.isClosed() && !shutdown) {
Socket clientSocket = serverSocket.accept();
ClientComponent clientComponent = new ClientComponent(this, clientSocket);
clientComponentSet.add(clientComponent);
clientComponent.start();
}
} catch (IOException e) {
LOGGER.error("Failed to start the server\n" + e.toString() + "\n");
}
}
最后,应该停止/关闭服务器的方法
public void stopServer() {
try {
serverSocket.close();
shutdown = true;
LOGGER.info("Server stopped\n");
} catch (IOException e) {
LOGGER.error(e.toString());
}
}
尽管如此,它并没有像我预期的那样工作。我启动然后停止我的服务器,日志如下所示:
2018-03-17 12:48:01 INFO Starting the server...
2018-03-17 12:48:02 INFO Established connection with database
2018-03-17 12:48:03 INFO Server started
2018-03-17 12:48:04 INFO Server stopped
2018-03-17 12:48:04 ERROR Failed to start the server java.net.SocketException: socket closed
现在尝试再次启动服务器,将会抛出
Exception in thread "JavaFX Application Thread" java.lang.IllegalThreadStateException
那么我该如何停止/关闭我的服务器呢?
我实际上忘记了我的 ServerController
类
public class ServerController {
final static Logger LOGGER = Logger.getLogger(ServerController.class);
private ServerController(){
}
private static ServerController instance = null;
public static ServerController getInstance() {
if(instance == null) {
instance = new ServerController();
}
return instance;
}
private Server server;
public void start() {
server = new Server(Integer.parseInt(Property.getByKey("SERVER_PORT")));
server.start();
if(!server.isAlive()) {
LOGGER.info("Server closed\n");
}
}
}
最佳答案
您至少可以修复一件令人困惑的事情,即使调用 closeServer()
,您的错误也会出现。
我建议;
- 您
关闭
volatile
- 你总是先设置它
- 检查服务器是否关闭,如果没有关闭则仅打印错误。
- 不要认为异常意味着它没有启动。
- 始终打印带有堆栈跟踪的异常以获取原因,除非您非常确信不需要它。
要重启一个线程,需要创建一个新的线程,要监听一个端口关闭后的端口,需要创建一个新的ServerSocket。
顺便说一句,您不需要在日志末尾添加额外的新行。
关于java - 终止线程的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49335706/