0

Java NIO を使用して Java tcp ソケット プログラミングを記述したいと考えています。その正常に動作します。しかし、クライアントからの読み取りと書き込みを受け入れるために同じセレクターを使用しています。

Java NIO で新しい接続を受け入れるためのさまざまなセレクターを作成して、読み取りと書き込みを行うにはどうすればよいですか。オンライン ヘルプはありますか。

実際、読み書きで忙しいときは、セレクターはより多くのイテレーターを使用します。そのため、より多くのクライアントが接続されている場合、新しい接続を受け入れるパフォーマンスが低下しました。しかし、受け入れるクライアントを遅くしたくありません

// セレクターを作成し、2 つのソケット チャネルを登録する Selector selector = null; try { // セレクターを作成する selector = Selector.open();

    // Create two non-blocking sockets. This method is implemented in
    // e173 Creating a Non-Blocking Socket.
    SocketChannel sChannel1 = createSocketChannel("hostname.com", 80);
    SocketChannel sChannel2 = createSocketChannel("hostname.com", 80);

    // Register the channel with selector, listening for all events
    sChannel1.register(selector, sChannel1.validOps());
    sChannel2.register(selector, sChannel1.validOps());
} catch (IOException e) {
}

// Wait for events
while (true) {
    try {
        // Wait for an event
        selector.select();
    } catch (IOException e) {
        // Handle error with selector
        break;
    }

    // Get list of selection keys with pending events
    Iterator it = selector.selectedKeys().iterator();

    // Process each key at a time
    while (it.hasNext()) {
        // Get the selection key
        SelectionKey selKey = (SelectionKey)it.next();

        // Remove it from the list to indicate that it is being processed
        it.remove();

        try {
            processSelectionKey(selKey);
        } catch (IOException e) {
            // Handle error with channel and unregister
            selKey.cancel();
        }
    }
}

public void processSelectionKey(SelectionKey selKey) throws IOException {
    // Since the ready operations are cumulative,
    // need to check readiness for each operation
    if (selKey.isValid() && selKey.isConnectable()) {
        // Get channel with connection request
        SocketChannel sChannel = (SocketChannel)selKey.channel();

        boolean success = sChannel.finishConnect();
        if (!success) {
            // An error occurred; handle it

            // Unregister the channel with this selector
            selKey.cancel();
        }
    }
    if (selKey.isValid() && selKey.isReadable()) {
        // Get channel with bytes to read
        SocketChannel sChannel = (SocketChannel)selKey.channel();

        // See e174 Reading from a SocketChannel
    }
    if (selKey.isValid() && selKey.isWritable()) {
        // Get channel that's ready for more bytes
        SocketChannel sChannel = (SocketChannel)selKey.channel();
        }
}

ありがとうディーパック

4

2 に答える 2

0

多くのオンライン ヘルプがあります。

新しいセレクターを作成する場合は、別のセレクターを作成してください (コピーしたサンプル コードで行ったのと同じ方法です)。必要に応じて、接続操作のためだけにチャネルを登録できます (ドキュメントではこれについて説明していますが、操作は OP_ACCEPT です)。おそらく、スレッド プールでクライアント処理の作業を処理する必要があります。これにより、メイン スレッドが作業項目をキューに入れ、リッスンしているソケットで新しい接続をすぐに受け入れることができるようになります。

于 2009-05-24T13:43:57.007 に答える
0

各セレクターには独自のスレッドが必要です。

複数のセレクターが必要な場合は、ブロッキング NIO を使用しない方簡単です。非ブロッキング IO は、スレッドを共有するために接続する場合にのみ意味があります。

于 2009-05-24T14:15:29.893 に答える