我正在开发一个Android应用程序,尝试从套接字上的一个线程执行非阻塞写入,同时在另一个线程上执行阻塞读取。我正在查看SocketChannel文档,并试图弄清楚configureBlocking究竟是做什么的。具体来说,如果我有一个非阻塞的SocketChannel,并且我使用socketChannel.socket()访问附属的Socket,那么Socket在某种程度上也是非阻塞的吗?还是阻止?
换句话说,通过为非阻塞方向设置非阻塞SocketChannel,并将附属Socket用于其他方向,我可以获得一个阻塞方向和一个非阻塞方向的效果吗?
答案 0 :(得分: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
}
}
}