3
我正在編寫一個連接到服務器的Android應用程序(> = 2.3),並且我遇到了NIO選擇器的問題。Android:Selector.select()立即返回0
Selector selector = SelectorProvider.provider().openSelector();
SocketChannel socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_READ);
selector.select(); // returns 0 immediately
公共抽象INT的select()
此方法不返回,直到至少一個信道準備好時,喚醒()被調用或調用線程被中斷。
和的情況下落入這些都不但它返回。 select()不像規範中描述的那樣運行,我認爲這是一個錯誤。
編輯
我在下面EJP的評論改變了代碼:
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();
}
當服務器在運行它的工作原理:選擇()1個選擇鍵返回,我可以打電話finishConnect()建立連接。但是如果服務器沒有運行,連接被拒絕,select()會返回0個選定的鍵。如果沒有選定的密鑰,我無法確定接下來要做什麼。 (並再次,這種情況並不在API文檔中描述的select()返回落入3個類別之一。)
感謝您的回覆。如果服務器關閉並且連接被拒絕,該怎麼辦?在這種情況下,select()返回0並且selectedKeys()爲空,那麼如何知道連接失敗並處理了這種情況? – 2013-05-06 08:34:18
問題是,當連接失敗時,select()會返回沒有正確設置selectedKeys()的值。即使連接失敗,也應該選擇密鑰,以便隨後調用finishConnect()可以捕獲異常以知道它失敗。這就是在Java文檔中指定的OP_CONNECT的行爲,如果Andoroid不遵循它,它就像一個錯誤。 – 2013-05-06 10:37:42
你錯過了這一點。在上面的代碼中,您正在調用select * *連接套接字。這是回到前面。在調用connect()之後,isConnectable()發生*,並且這是一個信號,您應該嘗試調用finishConnect()。這不是您現在可以調用connect()的信號。你不需要等待任何事情。 – EJP 2013-05-06 23:16:55