1

関連するコード -- 注意 命令は、データを操作するいくつかのメソッドを持つ単なるクラスです。新しいスレッドが作成され、読み取られたデータで動作します。

スレッドを読む:

while(true) {
     System.out.println(".");
     if(selector.select(500) == 0)
          continue;

     System.out.println("processing read");

     for(SelectionKey sk : selector.keys()) {
          Instructions ins = myHashTable.get(sk);
          if(ins == null) { 
               myHashTable.put(sk, new Instructions(sk));
               ins = myHashTable.get(sk);
          }
          ins.readChannel();
     }
}

READCHANNEL

public void readChannel() {
     BufferedReader reader = new BufferedReader(Channels.newReader((ReadableByteChannel) this.myKey.channel(), "UTF-8"));
     Worker w = new Worker(this, reader.readLine());
     (new Thread(w)).start();
}

その後、新しいスレッドはさらにInstructionsメソッドを呼び出します。

ins 関数が終了すると、Writer に書き込む場合があります。

Writer out = Channels.newWriter((WritableByteChannel) key.channel(), "UTF-8");
out.write(output);
out.flush();

クライアント (Flash ムービー) が出力を受信して​​処理することを確認できます。

最後に、w終了します。

ただし、クライアントから最初のメッセージを受信し、処理が成功した後は、READ THREADループによって処理されるメッセージはなくなります。キーはセレクターに登録されており、読み取る準備ができていると思います。すべてのキーをループして、チャンネルで isReadable と isRegistered で読み取れるかどうかを確認しましたが、これまでのすべてのケースで結果が true です。ただし、クライアントから 2 番目のメッセージが送信されると、読み取りスレッドに表示される唯一の応答は「.」文字は 0.5 秒ごとに出力されるのではなく、継続的に高速に出力されます。したがって、データはチャネルにあると思いますが、何らかの理由でセレクターがキーを選択していません。

誰でも私を助けることができますか?

4

3 に答える 3

3

ここでいくつかの点が欠けていると思います。

  • まず、
    Vijay が述べたように、for ループで selector.selectedKeys() を使用する必要があります。
  • キーが処理された後、selectedKeys からキーを削除する必要があります。そうしないと、キーが自動的に削除されないため、関心のある ops ビットが設定されたキーが 1 つある場合でも、セレクターが継続的に回転する可能性があります。(これはあなたの場合の問題かもしれません)。
  • 最後に、チャネルの準備ができている場合は、チャネルで操作を実行する必要があります。つまり、isReadable() が true を返す場合のみ読み取り、isWritable() が true の場合のみ書き込みを試みます。キーの検証を忘れないでください。
于 2011-09-06T19:14:08.460 に答える
2

すべきではない

for(SelectionKey sk : selector.keys()) 

なれ

for(SelectionKey sk : selector.selectedKeys())

現在の選択操作で発生したイベントのみを処理したいので?

select(500) が 5 秒前に返されると言うので、WRITE 操作のセレクターにチャネルを登録したと思います。ほとんどの場合、チャネルは書き込みの準備ができています。したがって、データが書き込み可能である場合にのみ、interest ops を WRITE に設定する必要があります。

于 2009-10-07T23:40:02.480 に答える
0

選択したキーのリストからチャネルを削除する必要があることに注意してください。Select() はそれを行いません。この目的にはイテレータを使用することをお勧めします。

Iterator<SelectionKey> key_interator = selector.selectedKeys().iterator();
while (key_interator.hasNext()) {
  ...
  key_interator.remove();
}
于 2011-07-22T11:38:01.943 に答える