ตกลงฉันทำงานนี้ในแบบที่ตอบคำถามของ OP โดยตรง
โปรดอ่านคำตอบสั้น ๆ ที่ผ่านมาสำหรับตัวอย่างของการใช้วิธีนี้
คำตอบสั้น ๆ :
ServerSocket myServer;
Socket clientSocket;
try {
myServer = new ServerSocket(port)
myServer.setSoTimeout(2000);
//YOU MUST DO THIS ANYTIME TO ASSIGN new ServerSocket() to myServer‼!
clientSocket = myServer.accept();
//In this case, after 2 seconds the below interruption will be thrown
}
catch (java.io.InterruptedIOException e) {
/* This is where you handle the timeout. THIS WILL NOT stop
the running of your code unless you issue a break; so you
can do whatever you need to do here to handle whatever you
want to happen when the timeout occurs.
*/
}
ตัวอย่างโลกแห่งความจริง:
ในตัวอย่างนี้ฉันมี ServerSocket รอการเชื่อมต่อภายในเธรด เมื่อฉันปิดแอพฉันต้องการปิดเธรด (โดยเฉพาะอย่างยิ่งซ็อกเก็ต) ในลักษณะที่สะอาดก่อนที่จะให้แอปปิดดังนั้นฉันจึงใช้. setSoTimeout () บน ServerSocket จากนั้นฉันใช้อินเทอร์รัปต์ที่โยน หลังจากหมดเวลาเพื่อตรวจสอบและดูว่าผู้ปกครองพยายามที่จะปิดกระทู้ ถ้าเป็นเช่นนั้นฉันจะปิดซ็อกเก็ตจากนั้นตั้งค่าสถานะที่ระบุว่าด้ายเสร็จแล้วฉันแยกออกจากวงวนเธรดที่ส่งกลับเป็นโมฆะ
package MyServer;
import javafx.concurrent.Task;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import javafx.concurrent.Task;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
public class Server {
public Server (int port) {this.port = port;}
private boolean threadDone = false;
private boolean threadInterrupted = false;
private boolean threadRunning = false;
private ServerSocket myServer = null;
private Socket clientSocket = null;
private Thread serverThread = null;;
private int port;
private static final int SO_TIMEOUT = 5000; //5 seconds
public void startServer() {
if (!threadRunning) {
serverThread = new Thread(thisServerTask);
serverThread.setDaemon(true);
serverThread.start();
}
}
public void stopServer() {
if (threadRunning) {
threadInterrupted = true;
while (!threadDone) {
//We are just waiting for the timeout to exception happen
}
if (threadDone) {threadRunning = false;}
}
}
public boolean isRunning() {return threadRunning;}
private Task<Void> thisServerTask = new Task <Void>() {
@Override public Void call() throws InterruptedException {
threadRunning = true;
try {
myServer = new ServerSocket(port);
myServer.setSoTimeout(SO_TIMEOUT);
clientSocket = new Socket();
} catch (IOException e) {
e.printStackTrace();
}
while(true) {
try {
clientSocket = myServer.accept();
}
catch (java.io.InterruptedIOException e) {
if (threadInterrupted) {
try { clientSocket.close(); } //This is the clean exit I'm after.
catch (IOException e1) { e1.printStackTrace(); }
threadDone = true;
break;
}
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
};
}
จากนั้นในคลาส Controller ของฉัน ... (ฉันจะแสดงเฉพาะรหัสที่เกี่ยวข้องนวดมันเป็นรหัสของคุณเองตามต้องการ)
public class Controller {
Server server = null;
private static final int port = 10000;
private void stopTheServer() {
server.stopServer();
while (server.isRunning() {
//We just wait for the server service to stop.
}
}
@FXML private void initialize() {
Platform.runLater(()-> {
server = new Server(port);
server.startServer();
Stage stage = (Stage) serverStatusLabel.getScene().getWindow();
stage.setOnCloseRequest(event->stopTheServer());
});
}
}
ฉันหวังว่านี่จะช่วยให้ใครบางคนเดินไปตามถนน