2011-07-20 79 views
1

我正在開發一個Android應用程序,試圖從一個套接字上的一個線程進行非阻塞寫入,同時在另一個線程上執行阻塞讀取。我正在瀏覽SocketChannel文檔,並試圖找出configureBlocking的功能。具體來說,如果我有一個非阻塞的SocketChannel,並且我使用socketChannel.socket()訪問附屬的Socket,那麼Socket在某種程度上也是非阻塞的嗎?還是阻塞?使用非阻塞的SocketChannel,是否阻塞了Socket?

換句話說,我可以通過在非阻塞方向上使用非阻塞SocketChannel,並在其他方向上使用附屬Socket來獲得一個阻塞方向和一個非阻塞方向的效果嗎?

回答

0

如果Socket有一個關聯的SocketChannel,則不能直接讀取它的InputStream。你會得到IllegalBlockingModeException。見here

您可以通過registering阻止非阻塞SocketChannel到Selector並使用select()select(long timeout)。這些方法通常會阻塞,直到註冊的通道準備就緒(或超時過期)。

對於不使用選擇器的線程,通道仍然是非阻塞的。

here

變形例:

Selector selector = Selector.open(); 
channel.configureBlocking(false); 

// register for OP_READ: you are interested in reading from the channel 
channel.register(selector, SelectionKey.OP_READ); 

while (true) { 
    int readyChannels = selector.select(); // This one blocks... 

    // Safety net if the selector awoke by other means 
    if (readyChannels == 0) continue; 

    Set<SelectionKey> selectedKeys = selector.selectedKeys(); 
    Iterator<SelectionKey> keyIterator = selectedKeys.iterator(); 

    while (keyIterator.hasNext()) { 
    SelectionKey key = keyIterator.next(); 

    keyIterator.remove(); 

    if (!key.isValid()) { 
     continue; 
    } else if (key.isAcceptable()) { 
     // a connection was accepted by a ServerSocketChannel. 
    } else if (key.isConnectable()) { 
     // a connection was established with a remote server. 
    } else if (key.isReadable()) { 
     // a channel is ready for reading 
    } else if (key.isWritable()) { 
     // a channel is ready for writing 
    } 
    } 
}