Reputation: 4743
I'm writing an Android app (>= 2.3) that connects to a server, and I have a problem with the NIO selector.
Selector selector = SelectorProvider.provider().openSelector();
SocketChannel socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_READ);
selector.select(); // returns 0 immediately
According to the Android API documentation,
public abstract int select ()
This method does not return until at least one channel is ready, wakeup() is invoked or the calling thread is interrupted.
and the case falls into none of these but it returns. select() doesn't behave as described in the specifications and I think it's a bug.
EDIT
I've changed the code upon EJP's comment below:
socketChannel.register(selector, SelectionKey.OP_CONNECT);
socketChannel.connect(serverAddress);
while (true) {
selector.select();
for (SelectionKey key: _selector.selectedKeys()) {
if (key.isConnectable())
finishConnect(key);
...
}
selector.selectedKeys().clear();
}
It works when the server is running: select() returns with 1 selected key, and I can call finishConnect() to establish the connection. But if the server is not running thus the connection is refused, select() returns 0 selected keys. If there's no selected key, there's no way I can determine what to do next. (and again, this case doesn't fall into one of the 3 categories when select() returns described in the API document.)
Upvotes: 3
Views: 1268
Reputation: 311023
Try connecting the socket to something before you register it. Either do that before you put it into non-blocking mode, or else do so afterwards but register OP_CONNECT instead of OP_READ and call finishConnect() when it fires: if it returns true, deregister OP_CONNECT and register OP_READ.
Upvotes: 0