0
votes

I want to write java tcp socket programming using java NIO. Its working fine. But I am using the same selector for accepting reading from and writing to the clients.

How Can I create different selectors for accepting new connection in java NIO, reading and writing. Is there any online help.

Actually when I am busy in reading or writing my selector uses more iterator. So If more number of clients are connected then performance of accepting new coneection became slow. But I donot want the accepting clients to be slow

// Create a selector and register two socket channels Selector selector = null; try { // Create the selector 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();
        }
}

Thanks Deepak

2
Clients are pre-accepted by the TCP stack. Thats what the backlog queue is for. The performance of that isn't affected by the performance of the iterator. Your question seems pretty pointless. You can increase the backlog easily enough, that's all you need.user207421

2 Answers

0
votes

There is plenty of online help.

If you want to create a new selector, go ahead and create another one (the same way it was done in the sample code you copied). You can register channels with it for just the connect operation if you want (the docs cover this, but the operation is OP_ACCEPT). You probably want a thread pool to handle the work of client processing - that way your main thread can queue up work items and get back onto accepting new connections on the listening socket right away.

0
votes

Each selector needs its own thread.

If you want multiple selectors, why not just use blocking NIO, that would be a lot simpler. Non-blocking IO only makes sense if you want to connections to share threads.