3

次のように、ノンブロッキング IO を使用して UDP パケットを取得する作業コードがあります。

DatagramChannel channel = DatagramChannel.open();
channel.socket().bind(new InetSocketAddress(AUDIO_PORT));
channel.configureBlocking(false);

while(true){
   ByteBuffer packet = ByteBuffer.allocate(MAX_PACKET);
   if(channel.receive(packet) != null){
      //Got something!
      ...
   }
   ...
}

それは完璧に機能します。今、私はまったく同じことをしようとしていますが、今回は次のようにセレクターを使用したいだけです:

//Create a datagram channel, bind it to port, configure non-blocking:

DatagramChannel channel = DatagramChannel.open();
channel.socket().bind(new InetSocketAddress(AUDIO_PORT));
channel.configureBlocking(false);

//Create a selector and register it:

Selector selector = Selector.open();
channel.register(selector, SelectionKey.OP_READ);

//Spin

while(true){

   //If there's a packet available, fetch it:

   if(selector.selectNow() >= 1){

       //**CODE NEVER REACHES THIS POINT**

       ByteBuffer packet = ByteBuffer.allocate(MAX_PACKET);
       channel.receive(packet);
       ...
   }
   ...
}

私が作成しているアプリケーションのために、(私の例では回転しているように見えますが) ノンブロッキング IO である必要があり、短いタイムアウトでのブロックは機能しません。また、セレクターも使用する必要があります。問題は、サーバーがアクティブにデバイスの AUDIO_PORT ポートにパケットを送信しているにもかかわらず、select() 操作が常に 0 を返すことです。セレクターの設定が間違っていますか? いくつかのステップが欠けていると思いますが、それを理解できません。

4

1 に答える 1

1

以前に他のスレッドで説明したように、最初のコードが機能し、2番目のコードが機能しない場合は、Androidでセレクターを壊す必要があります。コードは正しいです(ゼロ以外のリターンを受け取るたびにセレクターの選択されたキーセットをクリアする限り)。これは、Javaプラットフォームで実行することで確認できます。

一般性を高めるためにに変更select() == 1してからselect() > 0、すべての例でわかるように、選択したキーセットをループすることを検討できますが、このコードの正確性に影響を与えることはありません。

また、説明したと思いますが、セレクターの代わりに、読み取りタイムアウトを短くしてブロッキングモードを試すことができます。

NBあなたは回転していません、あなたは永遠にブロックしていますselect().

于 2013-02-04T23:02:21.983 に答える