2016-03-24 5 views
1

Говоря мое требование: Любой пользователь вводит что-то в консоли (из system.in) или сокет что-то получает, переходите к следующему шагу.Может java system.in работать вместе с исходным исходным кодом в то же время без использования нити

Поэтому у меня есть сканер

Scanner sc = new Scanner(System.in); 

У клиента UdP. (Другой источник входного сигнала)

DatagramSocket clientSocket = new DatagramSocket(); 

Мой код

while (true) { 
    if (sc.hasNext()) { 
     String str = sc.next(); 
     proceed(str) 
    } else { 
     clientSocket.receive(pack); 
     proceed(pack) 
    } 
} 

Очевидно, что этот код не будет работать. Потому что при проверке sc.hasNext() java ожидает, что пользователь наберет некоторый ввод в консоли. В настоящее время я могу открыть поток для Udp-клиента. Если изменить порядок,

while (true) { 
     clientSocket.receive(pack); 
     if (not receive) read from system.in 
    } 

Это не имеет смысла, так как получить() будет ждать Util получить что-то, он никогда не будет читать System.in одновременно.

Так как я могу достичь своего требования без использования нити?

Вдохновленный ответ @Andriy Kryvtsun, я сделал быстрый тест По его словам, это как-то с помощью неблокируемому чтения, и держать давая тайм-аут сокета, чтобы эмулировать

 InputStream ins = System.in; 
    byte buffer[] = new byte[512]; 
    BufferedReader reader = new BufferedReader(new InputStreamReader(ins)); 
    DatagramSocket clientSocket = new DatagramSocket(); 
    System.out.println("From buffer:" + clientSocket.getLocalPort()); 

    while (true) { 
     try { 
      if (ins.available() > 0) { 
       String line = reader.readLine(); 
       System.out.println("Read:" + line); 
      } else { 

       DatagramPacket pack = new DatagramPacket(buffer,buffer.length); 
       clientSocket.setSoTimeout(2000); 
       clientSocket.receive(pack); 
       System.out.println("Receive: " + new String(pack.getData())); 
      } 
     } catch (IOException e1) { 

     } 
    } 
+1

System.in - это блокирующий поток, поэтому нет предела тому, как долго он может блокироваться. Для обработки Socket вам нужно использовать поток (или два). –

+0

Похоже, вы можете использовать что-то из пакета 'java.nio.channels', но я не знаю, что именно, потому что я никогда не использовал его сам. Я бы использовал потоки для решения проблемы, которую вы описываете. –

+0

Да. Я также нашел те неблокирующие вещи. Поскольку требование не использовать поток. Я должен найти неблокирующий способ. – TTTTTAAOOOO

ответ

2

Используйте деблокировки метод звоните InputStream#available(), чтобы получить информацию, если что-то готовое для чтения перед использованием блокировки Scanner#hasNext() звонок.

Также вы можете позвонить по телефону DatagramSocket#setSoTimeout(int timeout) перед блокировкой вызова receive(DatagramPacket p). Таким образом, вы можете разбить бесконечность, ожидая внутри receive метод после timeout период подражания разблокировки чтения.

+0

Спасибо Andriy, это полезно. Я поставил здесь свой код. Единственное, если я устанавливаю таймаут как 2 секунды, когда я набираю что-то в консоли, мне нужно подождать около 1 секунды, чтобы распечатать его. Потому что он ждет тайм-аута. Я думаю, это то, чего мы не можем избежать. Пожалуйста, поправьте меня, если я ошибаюсь. – TTTTTAAOOOO

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

  • Нет связанных вопросов^_^