【发布时间】:2023-03-23 11:18:01
【问题描述】:
我有一个 Java 中的多线程 TCP 服务器,它允许来自多个客户端的连接,并为每个连接的客户端启动一个新的 ServerThread:
服务器类:
while (!Thread.currentThread().isInterrupted()) {
try {
// Create a new thread for each incoming connection.
Socket clientSocket = serverSocket.accept();
ServerThread serverThread = new ServerThread(clientSocket, this);
serverThread.run();
} catch (IOException e) {
e.printStackTrace();
}
}
在特定超时后,客户端关闭其套接字。如何中断与客户端连接的 ServerThread?
clientsocket.isClosed() 和 !clientSocket.isConnected() 由于某种原因无法正常工作。
最后,我用下面的 sn-ps 得到了它(解决方案是资源块中的套接字和无穷无尽的in.readLine() == null):
服务器类
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
// Create a new thread for each incoming connection.
Socket clientSocket = serverSocket.accept();
ServerThread serverThread = new ServerThread(clientSocket, this);
serverThread.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
ServerThread 类:
public void run() {
try (Socket socket = clientSocket; // Enable auto-close for socket...
PrintWriter out = ...; BufferedReader in = ...;) {
...
while (!clientSocket.isClosed() && !isInterrupted()) {
if (in.readLine() == null) {
break;
}
}
System.err.println("Client with port " + clientSocket.getPort() + " closed connection to server.");
} catch (IOException e) {
e.printStackTrace();
}
}
客户端类:我使用与 ServerThread 类中相同的资源块尝试
【问题讨论】:
-
1.您根本没有多线程服务器。你应该打电话给
serverThread.start(),而不是serverThread.run()。目前,您根本没有创建任何真正的线程。 2.isClosed()和isConnected()方法告诉你你的套接字的状态,而不是连接的状态。当对等方断开连接时,它们不会神奇地变为假。 3.不需要中断ServerThread。在这种情况下,从套接字读取会返回流的结尾:你在测试吗? -
但是如果我不中断ServerThread,过一段时间就会有大量的ServerThreads。
-
线程本身在读取时识别流结束,或在写入时识别 IOExceptions,或读取超时,并关闭其套接字并退出。这就是所有 Java 阻塞模式服务器的工作方式。您需要阅读 Java 教程的自定义网络部分。
标签: java multithreading sockets tcp server