在JavaNIO选择器中,我应该在什么时候注册';写入操作';?
我正在学习JavaNIO选择器。在我的理解中,我认为使用选择器的步骤是首先注册我的兴趣操作,然后检查就绪集,最后执行与我的兴趣操作相对应的操作。我不知道为什么在这段代码中,写入过程会发生在在JavaNIO选择器中,我应该在什么时候注册';写入操作';?,java,nio,Java,Nio,我正在学习JavaNIO选择器。在我的理解中,我认为使用选择器的步骤是首先注册我的兴趣操作,然后检查就绪集,最后执行与我的兴趣操作相对应的操作。我不知道为什么在这段代码中,写入过程会发生在if(key.isReadable()){…}块中,而不是if(key.iswriteable){…}块中,为什么写入操作没有注册 Iterator keys = sel.selectedKeys().iterator(); while (keys.hasNext()) { SelectionKey k
if(key.isReadable()){…}
块中,而不是if(key.iswriteable){…}
块中,为什么写入操作没有注册
Iterator keys = sel.selectedKeys().iterator();
while (keys.hasNext()) {
SelectionKey key = (SelectionKey)keys.next();
if (!key.isValid())
continue;
if (key.isAcceptable()) {
// increase the counter
connection++;
// remove accept request
keys.remove();
// ACCEPT: get the server channel
ServerSocketChannel ssc =
(ServerSocketChannel) key.channel();
// init a socket for a client
SocketChannel nsc = ssc.accept();
nsc.configureBlocking(false);
// register the socket for READ
nsc.register(sel, SelectionKey.OP_READ);
}
}
while (count < COUNT_MAX + NUM_CHILD - 1) {
sel.select();
// Get all pending events and iterate
Iterator keys = sel.selectedKeys().iterator();
while ( keys.hasNext() ) {
SelectionKey key = (SelectionKey)keys.next();
keys.remove();
if (!key.isValid())
continue;
if (key.isReadable()) {
// READ: get the channel
SocketChannel nsc = (SocketChannel) key.channel();
// clear buffer for reading
readBuffer.clear();
int nBytes = nsc.read(readBuffer);
if (nBytes == -1) {// Check if the client closed the socket
key.channel().close();
key.cancel();
continue;
}
// Read a message
DataInputStream ist = new DataInputStream (
new ByteArrayInputStream(readBuffer.array()));
String msg = ist.readUTF();
System.out.print(msg + "\n");
// Clear the write buffer
writeBuffer.clear();
// Write the counter value on the buffer
count++;
if (count < COUNT_MAX)
writeBuffer.putInt(count);
else
writeBuffer.putInt(-1);
// flip the buffer and write on the channel
writeBuffer.flip();
// Reply to a client
nsc.write(writeBuffer);
}
} // while (key)
Iterator key=sel.selectedKeys().Iterator();
while(keys.hasNext()){
SelectionKey=(SelectionKey)keys.next();
如果(!key.isValid())
继续;
if(key.isAcceptable()){
//增加计数器
连接++;
//删除接受请求
键。移除();
//接受:获取服务器通道
ServerSocketChannel ssc=
(ServerSocketChannel)key.channel();
//初始化客户端的套接字
SocketChannel nsc=ssc.accept();
nsc.configureBlocking(错误);
//注册套接字以进行读取
nsc寄存器(sel,SelectionKey.OP_READ);
}
}
while(count
您无需注册对OP_WRITE
的兴趣,因为通常频道已准备好写入。但是,如果处于非阻塞模式,则可能无法成功写入给定ByteBuffer
的所有内容。请参阅其java文档中的以下内容:
一些渠道,,
根据其状态,可能只写入部分字节或
可能根本没有。例如,非阻塞模式下的套接字通道
例如,写入的字节数不能超过套接字的可用字节数
输出缓冲区
在这种情况下,您需要在选择器上注册OP_WRITE
的兴趣,以便在频道再次准备好写入时收到通知,这样您就可以完成ByteBuffer
的写入
看这里一个相关的例子