[英]Multi thread socket server shutdown by message Java
我有一個多線程進程來監聽消息並處理它們。 如果收到的消息之一是“關閉”,我希望能夠關閉該過程。 除了關閉部分,我已經實現了所有內容。
我有一個“Multi”類,它使用start
方法擴展java.net.ServerSocket
。 里面...
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);
Collection<Socket> sockets = new ArrayList<>();
Collection<Thread> threads = new ArrayList<>();
try (ServerSocket socketServer = new ServerSocket(10101)) {
System.out.println("Started.");
while (running.get()) {
Socket socket = socketServer.accept();
sockets.add(socket);
if (running.get()) {
Thread thread = new Thread(new SocketHandler(socket, running));
thread.start();
threads.add(thread);
}
}
System.out.println("Stopping...");
sockets.forEach(socket -> {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
});
threads.forEach(thread -> {
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
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()))) {
boolean connected = true;
while (connected){
String command = in.readLine();
System.out.println("Command received: " + command);
if (command == null) {
connected = false;
} else if (command.equals("shutdown")) {
running.set(false);
try (Socket tmpSocket = new Socket("localhost", 10101)) {}
}
// process other commands
}
}
System.out.println("Client disconnected.");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
更新:更改示例以建立與服務器的連接以使其解除阻塞。
更新:處理客戶端斷開連接情況的示例代碼。 感謝@user207421 突出顯示這一點(謝謝)。
更新:更改了示例代碼以處理多個客戶端套接字/線程。 請注意,當您關閉當前剛剛打印到 stderr 的套接字時,它將通過異常。 您可能希望以不同的方式處理。
更新:您可能還會發現模擬多個客戶端連接的代碼很有幫助:
public class Clients {
public static void main(String[] args) {
Thread thread1 = new Thread(() -> new NormalClient().run());
Thread thread2 = new Thread(() -> new NormalClient().run());
Thread thread3 = new Thread(() -> new NormalClient().run());
Thread thread4 = new Thread(() -> new NormalClient().run());
Thread thread5 = new Thread(() -> new ShutdownClient().run());
thread1.start();
thread2.start();
thread3.start();
thread4.start();
thread5.start();
}
}
class NormalClient {
void run() {
try {
try (Socket socket = new Socket("localhost", 10101);
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()))) {
for (int i = 0; i < 10; i++) {
out.write("hello " + i);
out.newLine();
out.flush();
sleep(1000);
}
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
}
class ShutdownClient {
void run() {
try {
try (Socket socket = new Socket("localhost", 10101);
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()))) {
sleep(8000);
out.write("shutdown");
out.newLine();
out.flush();
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.