开发者

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.

I have a Server for a Console application, and users connect to it with any Telnet Client. 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. The ClienThread reads the client socket and sends the input (if any) to the ProcessingThread whic开发者_如何学JAVAh processes the input and performs the actions the user dictated. 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. 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.


I guess it is similar to the problems I faced yesterday You could invoke is.available() on your input stream and check whether data is available before doing a (blocking) read.


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. Set a read timeout on the Socket and have the reader thread check a 'cancel' flag every time it trips; set the flag from whereever you want to set it from.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜