StackOverflow와 Google을 둘러 보았고 문제에 대한 해결책을 찾을 수 없었으므로 여기에 제가하고있는 일이 있습니다.어떻게 프로그래밍 방식으로 InputStream에서 읽기를 취소 할 수 있습니까?
콘솔 응용 프로그램 용 서버가 있으며 사용자는 모든 텔넷 클라이언트와 연결됩니다. 세 개의 개별 스레드를 가진 클라이언트를 처리하고 있습니다. 하나의 스레드 (ClientThread)가 클라이언트에 대한 모든 프로그램 액세스를 제어하고, ClientThread는 입력을 처리하고 출력을 전송하는 두 개의 스레드를 유지합니다. ClienThread는 클라이언트 소켓을 읽고 입력을 처리하는 ProcessingThread에 입력 (있는 경우)을 보내고 사용자가 지시 한 작업을 수행합니다. 출력 스레드는 보낼 필요가있는 출력 대기열을 관리하고 대기 상태가 될 때마다 전송합니다. 사용자가 연결을 끊을 때 때때로 출력 대기열이 비어있을 때까지 연결이 유지되도록 연결을 설정하기 위해 연결이 종료되기 전에 Output "queue"에 남아있는 Output을 사용합니다. 그러나 소켓을 읽는 스레드 (그리고 더 이상 출력이 없을 때 궁극적으로 그것을 닫습니다.) 읽기에 걸려 있고 닫을 수 없습니다. 사용자가 연결을 끊을 때 소켓을 닫을 때까지는 문제가되지 않았습니다. 관련 코드를 알려 드리겠습니다.
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());
}
}
}
출력을 계속 보내야하므로 소켓을 닫지 않고 읽음을 취소 할 수 있습니다.
Stacker의 응답이 완벽하게 작동하는 동안 가져온 것처럼 여러 클라이언트에서 확장되지 않았습니다. 나는이 프로그램이 많은 수의 고객들을 지원할 것임을 의심 스럽다. 가능한 한 효율적으로 만들려고 시도하고있다. 마침내 해결 된 솔루션은 OutputThread에 'disconnect'알림이 전송되면 플래그가 변경되고 출력 큐에 대기열이 있으면 소켓을 닫으라는 클라이언트에 알리는 것입니다. 이렇게하면 출력 대기열을 지우는 데 몇 초가 더 오래 걸리는 모든 작업이 동일하게 유지됩니다. –