不是以通常的方式使用选择器,对于每个就绪通道,可以确定并发送消息,我想选择当前准备好的连接并在那里发送消息。
据推测,这可以通过将所有通道放入选择器进行读取并将它们标记为准备好进行读取(如果它们出来),然后执行相同的写入,然后从我已标记为准备好的那些中进行选择来完成。 / p>
这是一个好主意,有没有更好的方法来做到这一点,我应该注意什么?例如,Rox Tutorial状态“如果你试图混合使用OP READ和OP WRITE,你很快就会遇到麻烦。如果你这样做,Sun Windows实现就会陷入僵局。”这里有类似的陷阱吗?实施的最佳方式是什么:
boolean isReadyForRead(SocketChannel c);
boolean isReadyForWrite(SocketChannel c);
答案 0 :(得分:6)
当选择器唤醒时,您应该使用SelectionKey来验证套接字是否已准备好进行读取或写入。
这是关于编写NIO服务器和客户端的{em>非常有用的教程http://rox-xmlrpc.sourceforge.net/niotut/
答案 1 :(得分:2)
这样的事情怎么样?
public static boolean isReadyForRead(SocketChannel socket) throws IOException {
return isReady(socket, SelectionKey.OP_READ);
}
public static boolean isReadyForWrite(SocketChannel socket) throws IOException {
return isReady(socket, SelectionKey.OP_WRITE);
}
public static boolean isReady(SocketChannel socket, int op) throws IOException {
// Setup
if (socket.isBlocking())
throw new IllegalArgumentException("Socket must be in non-blocking mode");
Selector selector = SelectorProvider.provider().openSelector();
socket.register(selector, op);
// Real work
if (selector.selectNow() == 0)
return false;
// Just in case selector has other keys
return selector.selectedKeys().contains(socket.keyFor(selector));
}
此调用非常低效,因为它每次都进行设置。如果你有一个封闭的类,这应该移出。如果您知道选择器只包含一个键,则最后一行可以更改为“return true;
”。
我只是为了好玩而这样做。我想不出这会有用的场景。 Select()旨在有效地告诉您套接字的状态,每个人都应该直接使用它。