チャネルは、読み取りのための準備ができている場合、書き込みをチェックするJava NIO、

StackOverflow https://stackoverflow.com/questions/1450777

  •  12-09-2019
  •  | 
  •  

質問

の代わりにそれぞれ準備チャネルに対してメッセージを決定し、送信することができ、通常の方法、セレクタを使用する、私は現在準備ができている方の接続を選択し、そこにメッセージを送りたいです。

おそらくこれは、読書のためのセレクタにすべてのチャンネルを投げ、彼らが出てくる場合読み取るための準備ができて、それらをマーキングし、書き込み用に同じことをやって、その後、私は準備ができてマークしたものの中から選択することによって行うことができます。

これは良いアイデアです、これを行うには良い方法があり、私は何のために気を付ける必要がありますか?あなたはOP READとを混在しようとした場合たとえば、ロックスチュートリアルの状態は、 "をOPのWRITEすばやくトラブルに自分自身を取得します。日曜のWindowsの実装では、あなたがこれを行う場合にはデッドロックすることが確認されています。 "がここにあり同様の落とし穴はありますか?実施するための最良の方法は何ですかます:

boolean isReadyForRead(SocketChannel c);
boolean isReadyForWrite(SocketChannel c);
役に立ちましたか?

解決

どのようにこのようなものでしょうか?

public static boolean isReadyForRead(SocketChannel socket) throws IOException {
    return isReady(socket, SelectionKey.OP_READ);
}

public static boolean isReadyForWrite(SocketChannel socket) throws IOException {
    return isReady(socket, SelectionKey.OP_WRITE);
}

public static boolean isReady(SocketChannel socket, int op) throws IOException {
    // Setup
    if (socket.isBlocking()) 
        throw new IllegalArgumentException("Socket must be in non-blocking mode");

    Selector selector = SelectorProvider.provider().openSelector();
    socket.register(selector, op);

    // Real work
    if (selector.selectNow() == 0)
        return false;
    // Just in case selector has other keys
    return selector.selectedKeys().contains(socket.keyFor(selector));
}
それは、セットアップを毎回行いますので、

このコールはひどく非効率的です。あなたは、囲むクラスを持っている場合、これは外に移動する必要があります。あなたが1つのキーだけが含まれているセレクタ知っている場合は、最後の行は「return true;」に変更することができます。

私はちょうど楽しみのためにこれをやっています。私は、これは有用であろうシナリオを考えることはできません。選択し()効率的にあなたのソケットの状態を伝えるために設計されており、誰もが直接それを使用する必要があります。

他のヒント

あなたはセレクタが目覚めたときにソケットが、読み取りまたは書き込みのための準備ができているかどうか確認するためにあなたとSelectionKeyのを使用する必要があります。

ここでの非常にのNIOサーバーとクライアントの HTTPです//rox-xmlrpc.sourceforge.net/niotut/する

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top