pwas
pwas

Reputation: 3373

Check if OP_ACCEPT-ed Selection key has waiting connection to open

Consider that I've use selectors to handle user connections:

Initialization:

this.channel = ServerSocketChannel.open();

this.channel.socket().bind(new InetSocketAddress(4321));
this.channel.configureBlocking(false);

this.selector = Selector.open();
this.channel.register(selector, SelectionKey.OP_ACCEPT);

Main loop:

while (this.channel.isOpen()) {
    selector.select();
    for (SelectionKey key : this.selector.selectedKeys()) {
        if (key.isAcceptable()) this.acceptNewConnection(key);
        else if (key.isReadable()) this.readFromConnection(key); 
    }
}

Accepting connection:

private void acceptNewConnection(SelectionKey key) throws IOException {
    final SocketChannel channel = SelectionKeyHelpers.getServerSocketChannel(key).accept();
    final String address = SocketHelpers.getConnectorAddres(channel.socket());

    channel.configureBlocking(false);
    channel.register(this.selector, SelectionKey.OP_READ, address);
}

Eveything works almost fine... First connection is accepted and new selection key is added (with OP_READ).

The problem is that when some data is ready to read, selectedKeys() returns collection with two selection keys: the one to read and other with OP_OPEN despite there is no connection to access (in this case isAcceptable returns also true). So, getting socket from that SelectionKey (in acceptNewConncetion) returns null.

So.. is there any way to exclude selection key with OP_OPEN from selectedKeys() when there is no new connection available?

Is checking wheter socket channel == null is enough or there is more appropriate way? f.e:

final SocketChannel channel = SelectionKeyHelpers.getServerSocketChannel(key).accept();
if (channel == null) {
    // key is selected but there is nothing to accept
    return;
}

Upvotes: 0

Views: 147

Answers (1)

user207421
user207421

Reputation: 311023

  1. There is no such thing as OP_OPEN.
  2. The problem here is a bug in your code. You need to remove each processed key from the selected key set. The selector never does that.

Upvotes: 1

Related Questions