我有一个多线程进程,它侦听消息并对其进行处理。如果收到的消息之一是“ shutdown”,我希望能够关闭该进程。除了关机部分,我已经实现了所有功能。
我有一个用java.net.ServerSocket
方法扩展start
的“多”类。里面...
java.net.Socket socket = null;
while (true) {
try {
socket = this.accept();
new Thread(new SocketThread(socket, verifier, threading)).start();
} catch (IOException e) {
e.printStackTrace();
}
}
那个SocketThread是implements Runnable
的另一个类。有什么办法可以使这项工作完成?
我以前不必这样做(因为我通常不会发现自己必须写大量的原始SocketServer),但是使用这种类型的线程协调,我会尝试执行以下操作……
public class App {
public static void main(String[] args) {
new App().run();
}
public void run() {
try {
System.out.println("Starting...");
AtomicBoolean running = new AtomicBoolean(true);
try (ServerSocket socketServer = new ServerSocket(10101)) {
while (running.get()) {
System.out.println("Started.");
Socket socket = socketServer.accept();
System.out.println("Connection accepted.");
if (running.get()) {
Thread thread = new Thread(new SocketHandler(socket, running));
thread.start();
} else {
System.out.println("Stopping...");
}
}
}
System.out.println("Stopped.");
} catch (IOException e) {
e.printStackTrace();
}
}
static class SocketHandler implements Runnable {
private final Socket socket;
private final AtomicBoolean running;
SocketHandler(Socket socket, AtomicBoolean running) {
this.socket = socket;
this.running = running;
}
@Override
public void run() {
try {
System.out.println("Client connected.");
try (BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()))) {
String command = in.readLine();
while (command != null && !command.equals("shutdown")){
// process command
System.out.println("Command: " + command);
command = in.readLine();
}
if (!"shutdown".equals(command)) {
System.out.println("Shutdown command received");
running.set(false);
try (Socket tmpSocket = new Socket("localhost", 10101)) {}
}
}
System.out.println("Client disconnected.");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Updated:处理客户端断开连接的示例代码。感谢@ user207421突出显示此内容(谢谢)。
我不太确定Java Socket API的可中断性,但为此我投入了一些代码,就好像您在等待accept()
一样,那么只会在下一个连接上检查运行标志(您可能需要考虑使用interrupt()
的替代方法)。希望对您有所帮助。
更新:更改了示例,以建立与服务器的连接以使其解除阻止。
注意:请确保在退出前清理Socket资源。我没有包括使代码尽可能简短。
更新:您可能还会发现此测试有用:
public class RawSocketServerTest {
@Test
public void should_shutdown_when_sent_shutdown_command() throws IOException, InterruptedException {
// given
Thread thread = new Thread(() -> { new App().run(); });
thread.start();
sleep(1000); // waiting for App to start; replace with something more robust (e.g. awaitility)
Socket socket = new Socket("localhost", 10101);
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
// when
out.write("shutdown");
out.newLine();
out.flush();
// then
thread.join(); // App exited normally
}
}