Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在JavaNIO选择器中,我应该在什么时候注册';写入操作';?_Java_Nio - Fatal编程技术网

在JavaNIO选择器中,我应该在什么时候注册';写入操作';?

在JavaNIO选择器中,我应该在什么时候注册';写入操作';?,java,nio,Java,Nio,我正在学习JavaNIO选择器。在我的理解中,我认为使用选择器的步骤是首先注册我的兴趣操作,然后检查就绪集,最后执行与我的兴趣操作相对应的操作。我不知道为什么在这段代码中,写入过程会发生在if(key.isReadable()){…}块中,而不是if(key.iswriteable){…}块中,为什么写入操作没有注册 Iterator keys = sel.selectedKeys().iterator(); while (keys.hasNext()) { SelectionKey k

我正在学习JavaNIO选择器。在我的理解中,我认为使用选择器的步骤是首先注册我的兴趣操作,然后检查就绪集,最后执行与我的兴趣操作相对应的操作。我不知道为什么在这段代码中,写入过程会发生在
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
的写入

看这里一个相关的例子