2012-06-04 4 views
1

Я пытаюсь создать непрерывный поток, где сервер получает/отправляет сообщения от клиента, однако, когда я пытаюсь проверить, что следующий элемент застрял:Как обходить сканер проверить следующий элемент (если это имеет смысл)

public void run() 
{ 
    try 
    { 
     try 
     { 
      ArrayList<Socket> connections = parent.getConnections(); 
      in = new Scanner(socket.getInputStream()); 

      while(true) 
      { 
       if(in.hasNextLine()) // Gets stuck here 
       { 
        String message = in.nextLine(); 
        System.out.println("Client said " + message); 
       } 
      } 
     } 

     finally 
     { 
      socket.close(); 
     } 
    } 

    catch(Exception e) 
    { 
     e.printStackTrace(); 
    } 

Как сделать цикл не застревают в указанной точке

+1

Определить «застрял». Сокеты позволяют асинхронную связь? Где ваша внутренняя фраза 'catch', или какой смысл? Не отключайте все исключения - используйте только те, которые вы можете учитывать (за исключением самого высокого уровня приложения). Не используйте 'while (true)' - проверьте какое-то условие, поэтому цикл можно безопасно отключить; в настоящее время пользователю нужно будет убить поток через какой-то диспетчер потоков (скажем, TaskManager), а не приятную перспективу. –

+0

Застревание Я имею в виду, что он не завершает цикл и ждет выхода из потока. Только при выходе от клиента цикл будет завершен. Я исправил инструкции try/catch, а цикл while (true) не является проблемой. – mudassir

+0

Это говорит о том, что поток, возвращаемый из 'socket.getInputStream()', является «блокировкой», то есть он ожидает ввода. Вероятно, вам нужно выполнить одно из следующих действий: 1) обернуть поток, первоначально полученный в тот, который не будет блокировать 2) установить опцию 'TIMEOUT' для сокета (и уловить полученное исключение) 3) использовать потоки и очереди, чтобы остальная часть вашей программы может продолжаться независимо от состояния входного сокета (это, вероятно, лучший вариант и может быть несколько скомбинирован с другими). –

ответ

1

Предполагая, что вы хотите быть в состоянии иметь дело с «линий», я бы, вероятно, начать с чего-то вроде этого:

public class SocketReader implements Runnable { 

    private final InputStream stream; 
    private final Queue<String> destination; 
    private volatile boolean active = true; 

    private SocketReader(InputStream stream, Queue<String> destination) { 
     this.stream = stream; 
     this.destination = destination; 
    } 

    public static SocketReader getReader(Socket toRead, Queue<String> destination) throws IOException { 
     return new SocketReader(toRead.getInputStream(), destination); 
    } 

    public void shutdown() { 
     active = false; 
    } 

    public void run() { 
     while(active) { 
      if (stream.hasNextLine() && active) { 
       final String line = stream.nextLine; 
       destination.add(line); 
      } 
     } 
     try { 
      stream.close(); 
     } catch (IOException e) { 
      // Log somewhere 
     } 
    } 
} 

Поместите это в свой поток (или как часть потока или пула исполнителей, действительно), и вы сделали остальную часть вашего приложения неблокирующимся в отношении этого кода. EXPECT это для блокировки при ожидании обновлений от stream.hasNextLine(). Вы даже можете поставить BlockingQueue, если вы не хотите активно опросить очередь, но обрабатываете обновления каким-либо другим способом.

Вы можете сделать что-то подобное для вывода:

public class QueuedPrinter implements Runnable { 

    private final Queue<String> input; 
    private final PrintStream destination; 
    private volatile boolean active; 

    public QueuedPrinter(Queue<String> input, PrintStream destination) { 
     this.input = input; 
     this.destination = destination; 
    } 

    public void shutdown() { 
     active = false; 
    } 

    public void run() { 
     while(active) { 
      final String line = input.poll(); 
      if (line != null && active) { 
       destination.println(line); 
      } 
     } 
    } 

} 

Пожалуйста, обратите внимание, что я не проверял это, и вы, возможно, придется настроить вещи немного для других проверяемых исключений. Вероятно, вам нужно добавить дополнительный код проверки ошибок (наводит на мысль о нулевой обработке). Кроме того, это не полностью threadsafe, но, вероятно, будет «достаточно хорошим» для большинства целей.

+0

Большое вам спасибо! Это очень помогает. Извините за поздний ответ, я был озабочен. – mudassir

Смежные вопросы