【发布时间】:2011-11-16 13:10:18
【问题描述】:
我环顾 StackOverflow 和 Google,但无法找到解决问题的方法,所以这就是我正在做的事情。
我有一个控制台应用程序的服务器,用户使用任何 Telnet 客户端连接到它。我正在使用三个单独的线程处理客户端,一个线程 (ClientThread) 控制对客户端的所有程序访问,ClientThread 维护两个线程,一个用于处理输入,一个用于发送输出。 ClienThread 读取客户端套接字并将输入(如果有)发送到处理输入并执行用户指示的操作的处理线程。输出线程管理一个需要发送的输出队列,并在每次唤醒时发送。当用户断开连接时,我偶尔会使用在连接终止之前留在输出“队列”中的输出,所以我想设置它以便连接保持活动状态,直到输出队列为空 - 但是读取套接字的线程(并最终在没有更多输出时关闭它)挂在读取上,我无法关闭它。在用户断开连接之前,这不是问题,我只是关闭了 Socket。我给你相关代码。
public class ClientThread extends Thread {
// Initialization and other code not pertaining to the problem
public void run() {
while (connected) {
try {
String input = in.readLine();
if (input != null) {
processor.queue(TextUtility.processBackspaceChars(input));
timeoutTimer.interrupt();
}
} catch (Exception e) {
if (e.getMessage() != null && !(e.getMessage().equals("socket closed")))
server.appendError("Issue reading from client: "
+ getClientDisplayInfo() + "\n"
+ "&r-The issue is:&w- " + e.getMessage() + "&r-.");
}
}
while (disconnecting) {
try {
if (outputThread.hasOutput()) {
sleep(10);
} else {
disconnecting = false;
outputThread.disconnect();
client.close();
}
} catch (Exception exc) {
server.appendError("Failed to close the Thread for client: " + getClientDisplayInfo());
}
}
}
public void disconnect() {
try {
connected = false;
disconnecting = true;
processor.disconnect();
timeoutTimer.disconnect();
in.close(); // This is the BufferedReader that reads the Socket Input Stream
this.interrupt(); // This was my attempt to break out of the read, but it failed
} catch (Exception e) {
server.appendError("Failed to close the Thread for client: "
+ getClientDisplayInfo());
}
}
}
我只是好奇如何在不关闭 Socket 的情况下取消读取,因为我需要继续发送输出。
【问题讨论】:
-
虽然 Stacker 的响应运行良好,但由于它已被提出,但它无法与多个客户端一起扩展。我怀疑这个程序是否会支持大量客户,我仍在努力使其尽可能高效。我最终确定的解决方案是,当发送 OutputThread 时,
disconnect通知标志被更改,并且一旦它的输出队列清空,它就会通知客户端关闭套接字。这可以让所有东西在这几秒钟内以相同的方式运行以清除输出队列。
标签: java multithreading sockets inputstream