Как вы можете программно отменить чтение из InputStream? - PullRequest
3 голосов
/ 14 сентября 2011

Я просмотрел StackOverflow и с Google и не смог найти решение моей проблемы, поэтому вот что я делаю.

У меня есть сервер для консольного приложения, и пользователи подключаются к нему с помощью любого клиента Telnet.Я работаю с Клиентами с тремя отдельными потоками, один поток (ClientThread) контролирует весь доступ Программы к Клиенту, ClientThread поддерживает два потока, один для обработки ввода и один для отправки вывода.ClienThread считывает сокет клиента и отправляет ввод (если есть) в ProcessingThread, который обрабатывает ввод и выполняет действия, продиктованные пользователем.Выходной поток управляет очередью вывода, которую необходимо отправить, и отправляет ее при каждом пробуждении.Когда пользователь отключается, я иногда использую вывод, который остается в «очереди» вывода до разрыва соединения, поэтому я хотел установить его так, чтобы соединение поддерживалось до тех пор, пока очередь вывода не станет пустой - однако поток, который читает сокети в конечном итоге закрывает его, когда больше нет вывода) висит на чтение, и я не могу закрыть его.Это не было проблемой раньше, когда после отключения пользователя я просто закрывал 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());
      }
   }
}

Мне просто любопытно, как я могу отменить чтение, не закрывая сокет, так как мне нужно продолжать отправлять вывод.

Ответы [ 2 ]

4 голосов
/ 14 сентября 2011

Полагаю, это похоже на проблемы, с которыми я столкнулся вчера Вы можете вызвать is.available() в своем входном потоке и проверить, доступны ли данные перед выполнением (блокирующего) чтения.

3 голосов
/ 14 сентября 2011

Не вызывайте available (): либо вы тратите слишком много времени на вызовы ЦП, либо вы тратите время на то, чтобы не вызывать его достаточно часто, поэтому время отклика снижается. Установите тайм-аут чтения на сокете и заставьте поток чтения проверять флаг «отмены» каждый раз, когда он срабатывает; установите флаг там, где вы хотите установить его.

...