サーチ…


備考

SelectionKeyは、 SelectorChannelの間で異なる選択可能な操作と情報を定義します。特に、接続関連情報を格納するために添付ファイルを使用することができます。

OP_READ処理は簡単です。ただし、 OP_WRITEを扱うときは注意が必要OP_WRITE 。ほとんどの場合、データはソケットに書き込まれるため、イベントは発火し続けます。 OP_WRITEデータを書き込む前に登録する必要があります( その回答を参照)。

また、 OP_CONNECTチャンネルが接続されていたら(まあ、それが接続されている 、ので。を参照してください。キャンセルする必要があるこれをし、 そのように回答可)。したがって、 OP_CONNECT finishConnect()後のOP_CONNECT削除は成功しました。

セレクタを使用してイベントを待機する(OP_CONNECTの例)

NIOはJava 1.4に登場し、通常のI / Oよりも速いと思われる「チャネル」の概念を導入しました。ネットワーク上では、 SelectableChannelはチャンネルのさまざまな状態を監視できるので、最も興味深いものです。これは、C select()システムコールと同じように動作します。特定の種類のイベントが発生したときに起きる:

  • 受信した接続( OP_ACCEPT
  • 接続が実現された( OP_CONNECT
  • リードFIFO( OP_READ )で利用可能なデータ
  • データをFIFO( OP_WRITE )に書き込むことができます。

それは、ソケットI / Oの検出 (何かが読み書き可能...)とI / O(読み込み/書き込み/ ...)を実行することの間の分離を可能にします。特に、すべてのI / O検出は複数のソケット(クライアント)に対して1つのスレッドで実行できますが、I / Oの実行はスレッドプールやその他の場所で処理できます。これにより、アプリケーションを接続されたクライアントの数に容易に拡大することができます。

次の例は、基本を示しています。

  1. Selector作成する
  2. SocketChannel作成
  3. Selector SocketChannelを登録する
  4. Selectorを使用してイベントを検出するループ
Selector sel = Selector.open(); // Create the Selector
SocketChannel sc = SocketChannel.open(); // Create a SocketChannel
sc.configureBlocking(false); // ... non blocking
sc.setOption(StandardSocketOptions.SO_KEEPALIVE, true); // ... set some options

// Register the Channel to the Selector for wake-up on CONNECT event and use some description as an attachement
sc.register(sel, SelectionKey.OP_CONNECT, "Connection to google.com"); // Returns a SelectionKey: the association between the SocketChannel and the Selector
System.out.println("Initiating connection");
if (sc.connect(new InetSocketAddress("www.google.com", 80)))
    System.out.println("Connected"); // Connected right-away: nothing else to do
else {
    boolean exit = false;
    while (!exit) {
        if (sel.select(100) == 0) // Did something happen on some registered Channels during the last 100ms?
            continue; // No, wait some more
        
        // Something happened...
        Set<SelectionKey> keys = sel.selectedKeys(); // List of SelectionKeys on which some registered operation was triggered
        for (SelectionKey k : keys) {
            System.out.println("Checking "+k.attachment());
            if (k.isConnectable()) { // CONNECT event
                System.out.print("Connected through select() on "+k.channel()+" -> ");
                if (sc.finishConnect()) { // Finish connection process
                    System.out.println("done!");
                    k.interestOps(k.interestOps() & ~SelectionKey.OP_CONNECT); // We are already connected: remove interest in CONNECT event
                    exit = true;
                } else
                    System.out.println("unfinished...");
            }
            // TODO: else if (k.isReadable()) { ...
        }
        keys.clear(); // Have to clear the selected keys set once processed!
    }
}
System.out.print("Disconnecting ... ");
sc.shutdownOutput(); // Initiate graceful disconnection
// TODO: emtpy receive buffer
sc.close();
System.out.println("done");

次のように出力されます。

Initiating connection
Checking Connection to google.com
Connected through 'select()' on java.nio.channels.SocketChannel[connection-pending remote=www.google.com/216.58.208.228:80] -> done!
Disconnecting ... done


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow