简体   繁体   English

你怎么能以编程方式取消从InputStream读取?

[英]How can you programatically cancel reading from an InputStream?

I've looked around StackOverflow and with Google and was unable to find a solution to my problem, so here's what I'm doing. 我查看了StackOverflow和谷歌,但无法找到问题的解决方案,所以这就是我正在做的事情。

I have a Server for a Console application, and users connect to it with any Telnet Client. 我有一个控制台应用程序的服务器,用户使用任何Telnet客户端连接到它。 I'm handling Clients with three separate threads, one thread (ClientThread) controls all Program access to a Client, the ClientThread maintains two threads, one for processing input and one for sending output. 我正在处理具有三个独立线程的客户端,一个线程(ClientThread)控制对客户端的所有程序访问,ClientThread维护两个线程,一个用于处理输入,一个用于发送输出。 The ClienThread reads the client socket and sends the input (if any) to the ProcessingThread which processes the input and performs the actions the user dictated. ClienThread读取客户端套接字并将输入(如果有)发送到ProcessingThread,ProcessingThread处理输入并执行用户指定的操作。 The output Thread manages a queue of output that needs to be sent and sends it each time it wakes up. 输出线程管理需要发送的输出队列,并在每次唤醒时发送它。 When a user disconnects I occasionally use Output that's left in the Output "queue" before the connection is terminated so I wanted to set it up so that the connection was kept alive until the Output Queue is empty - however the Thread that reads the socket (and ultimately closes it when there is no more output) is hanging on the read and I'm unable to close it. 当用户断开连接时我偶尔会在连接终止之前使用输出“队列”中剩下的输出,所以我想设置它以便连接保持活动直到输出队列为空 - 但是读取套接字的线程(并且当没有更多输出时最终关闭它)挂在读取上,我无法关闭它。 This wasn't a problem before when, upon the user disconnecting, I just closed the Socket. 在用户断开连接之前,我刚关闭了Socket,这不是问题。 I'll give you the relevant code. 我会给你相关的代码。

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());
      }
   }
}

I'm just curious how I can cancel the read without closing the Socket since I need to continue sending output. 我只是好奇如何在不关闭Socket的情况下取消读取,因为我需要继续发送输出。

我想它类似于我昨天遇到的问题您可以在输入流上调用is.available()并在执行(阻塞)读取之前检查数据是否可用。

Don't call available(): either you waste CPU calling it too frequently, or you waste time not calling it frequently enough, so your reponse times suffer. 不要叫可用():要么浪费CPU太频繁地调用它,要么浪费时间不要经常调用它,所以你的响应时间会受到影响。 Set a read timeout on the Socket and have the reader thread check a 'cancel' flag every time it trips; 在Socket上设置读取超时并让读取器线程在每次跳闸时检查“取消”标志; set the flag from whereever you want to set it from. 从您想要设置的标志设置标志。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM