2016-03-24 11 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はブロッキングストリームなので、ブロックする時間の制限はありません。ソケット処理にはスレッド(または2つ)を使用する必要があります。 –

+0

'java.nio.channels'パッケージから何かを使いたいと思うかもしれませんが、私は自分自身を使ったことがないので正確に何を知りません。あなたが記述した問題を解決するためにスレッドを使用します。 –

+0

はい。私はまた、それらの非ブロッキングなものを発見した。 requriementはスレッドを使用しないためです。私はノンブロッキングな方法を見つけなければなりません。 – TTTTTAAOOOO

答えて

2

使用ブロック解除方法をエミュレートするために、非ブロック読み取りを使用して、ソケットのタイムアウトをさせる維持されます電話番号InputStream#available()を呼び出して、何かが読めるように準備が整っていれば、Scanner#hasNext()ブロッキングを使用する前に情報を入手してください。

も、receive(DatagramPacket p)メソッドの呼び出しをブロックする前に呼び出すことができます。したがって、timeoutの期間を待ってから、receiveメソッドの中で待っている無限大を壊すことができます。

+0

ありがとうAndriy、これは役に立ちます。私はここに自分のコードを入れました。唯一のことは、タイムアウトを2秒に設定した場合、コンソールに何かを入力すると、それを印刷するのに約1秒かかることがあります。タイムアウトを待っているからです。これは避けられないものだと私は思う。私が間違っているなら、私を修正してください。 – TTTTTAAOOOO

関連する問題