由于我为此被困了一个星期,但仍然没有弄清楚,所以我尝试尽可能清楚地表达我想要的内容。
我有一个可以处理多个客户端并与它们通信的服务器。 每当客户端连接时,服务器都会将客户端的请求传递给我的 RequestHandler 类,其中正在处理客户端命令。 如果其中一个客户端说“SHUTDOWN”,服务器应该将它们松开并关闭。 这不起作用。 如果只有一个客户端连接到服务器,服务器似乎卡在accept()调用中,我不知道如何解决这个问题。
已经有一个回复,但请不要注意它,它是关于另一个已过时的主题
我有两种方法,但似乎都不起作用。 1)如果客户端写入“SHUTDOWN”,则shutdownFlag设置为true(希望退出while循环) 2)如果客户端写入“SHUTDOWN”,则在服务器上调用静态方法 shutdown(),这应该将其关闭
下面你可以看到我的Server类的实现,涉及的另外两个类是Client(他所做的只是连接到Socket)和RequestHandler(这个类处理Input并写入它)。 我 98% 确信问题出在 Server 类中。
下面是服务器的更短版本,只有方法,没有任何控制台输出,这可能有助于理解它,以防您想复制代码
public class Server {
public static final int PORTNUMBER = 8540;
public static final int MAX_CLIENTS = 3;
public static boolean shutdownFlag = false;
public static ExecutorService executor = null;
public static ServerSocket serverSocket = null;
public static void main(String[] args) {
ExecutorService executor = null;
try (ServerSocket serverSocket = new ServerSocket(PORTNUMBER);) {
executor = Executors.newFixedThreadPool(MAX_CLIENTS);
System.out.println("Waiting for clients");
while (!shutdownFlag) {
System.out.println("shutdown flag ist : " + shutdownFlag);
Socket clientSocket = serverSocket.accept();
Runnable worker = new RequestHandler(clientSocket);
executor.execute(worker);
System.out.println("Hallo");
}
if (shutdownFlag) {
System.out.println("Flag is on");
try {
executor.awaitTermination(10, TimeUnit.SECONDS);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
//Stop accepting requests.
serverSocket.close();
} catch (IOException e) {
System.out.println("Error in server shutdown");
e.printStackTrace();
}
serverSocket.close();
}
System.out.println("shutting down");
} catch (IOException e) {
System.out
.println("Exception caught when trying to listen on port "
+ PORTNUMBER + " or listening for a connection");
System.out.println(e.getMessage());
} finally {
if (executor != null) {
executor.shutdown();
}
}
}
public static void shutdown(){
if (shutdownFlag) {
System.out.println("Flag is on");
try {
executor.awaitTermination(10, TimeUnit.SECONDS);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
//Stop accepting requests.
serverSocket.close();
} catch (IOException e) {
System.out.println("Error in server shutdown");
e.printStackTrace();
}
try {
serverSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
<小时/>
public class Server {
public static final int PORTNUMBER = 8540;
public static final int MAX_CLIENTS = 3;
public static boolean shutdownFlag = false;
public static ExecutorService executor = null;
public static ServerSocket serverSocket = null;
public static void main(String[] args) {
ExecutorService executor = null;
try (ServerSocket serverSocket = new ServerSocket(PORTNUMBER);) {
executor = Executors.newFixedThreadPool(MAX_CLIENTS);
while (!shutdownFlag) {
Socket clientSocket = serverSocket.accept();
Runnable worker = new RequestHandler(clientSocket);
executor.execute(worker);
}
if (shutdownFlag) {
try {
executor.awaitTermination(10, TimeUnit.SECONDS);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
serverSocket.close();
}
} catch (IOException e) {
} finally {
if (executor != null) {
executor.shutdown();
}
}
}
public static void shutdown() {
if (shutdownFlag) {
try {
executor.awaitTermination(10, TimeUnit.SECONDS);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
最佳答案
如果您将代码移至 main
进入 Server
上的实例方法(我们会在这里说 run
)你可以这样做 new Server().run()
里面main
。这样你就有一个实例( this
)可以在你的 run
中使用。方法。
像这样的事情:
class Server {
private boolean shutdownFlag = false; // This can't be static anymore.
public static final Server SERVER = new Server();
public static void main(String[] args) {
SERVER.run();
}
private void run() {
// Here goes everything that used to be inside main...
// Now you have the Server.SERVER instance to use outside the class
// to shut things down or whatever ...
}
}
这个模式实际上并不是那么好,但更好的是在这里太长了。希望这能让您有一个良好的开端。
关于java - 线程服务器卡在accept()上又名如何通过客户端输入关闭多线程服务器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39756825/