简体   繁体   English

boost :: asio :: async_read继续在命名管道上返回eof

[英]boost::asio::async_read keeps returning eof on named pipe

Here is my sample code that opens a pipe in read mode. 这是我的示例代码,以读取模式打开管道。 It uses boost::asio to read from the pipe. 它使用boost::asio从管道读取。 When data (let's say X bytes) is written to the pipe, it calls on_read with ec=EOF , bytes=X and X bytes of data in the buffer. 当数据(比如说X个字节)被写入管道时,它将调用ec=EOF on_readbytes=X和缓冲区中X个字节的数据。

EOF is sent because the writer, after finishing writing to the pipe, closes it. 之所以发送EOF,是因为编写器在完成对管道的写入之后将其关闭。 I want to keep reading. 我想继续读书。 That is why I call pipe.async_wait() in on_read . 这就是为什么我在on_read调用pipe.async_wait()on_read However, even if nothing is ready to be read from the pipe, on_read calls my_pipe::async_read() which again calls on_read() with bytes = 0 and ec=EOF . 但是,即使没有准备好从管道中读取任何内容, on_read调用my_pipe::async_read() ,后者会再次以bytes = 0ec=EOF调用on_read() This goes on in an infinite loop. 这是无限循环的。

Why does it keeping reading EOF repeatedly? 为什么它会不断读取EOF

#include <boost/asio/io_service.hpp>
#include <boost/asio/placeholders.hpp>
#include <boost/asio/posix/stream_descriptor.hpp>
#include <unistd.h>
#include <chrono>
#include <cstdint>
#include <fstream>
#include <iostream>
#include <string>
#include <boost/asio/read.hpp>
#include <boost/asio/write.hpp>
#include <boost/bind.hpp>


class my_pipe final
{
public:
    explicit my_pipe(boost::asio::io_service& io_service);
    ~my_pipe();
private:
    boost::asio::posix::stream_descriptor pipe;
    std::vector<char> _buf{};
    void async_read(const boost::system::error_code& ec);
    void on_read(const boost::system::error_code& ec, std::size_t bytes_transferred);
};

my_pipe::my_pipe(boost::asio::io_service& io_service) : pipe(io_service)
{
    int fd = open("/tmp/pipe1", O_RDONLY | O_NONBLOCK);
    if (fd == -1)
        return;

    _buf.resize(8192);
    pipe.assign(fd);
    pipe.async_wait(boost::asio::posix::stream_descriptor::wait_read,
        boost::bind(&my_pipe::async_read, this, boost::asio::placeholders::error));
}

my_pipe::~my_pipe()
{
    pipe.close();
}

void my_pipe::async_read(const boost::system::error_code& ec)
{
    std::cout << "async_read\n";
    if (ec)
        return;
    boost::asio::async_read(pipe, boost::asio::buffer(_buf),
        boost::bind(&my_pipe::on_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
}

void my_pipe::on_read(const boost::system::error_code& ec, std::size_t bytes)
{
    std::cout << "on_read. bytes=" << bytes << "\n";
    if (!ec || ec == boost::asio::error::eof) {
        if (ec == boost::asio::error::eof)
            std::cout << "eof\n";
        std::cout << "call async_read\n";
        pipe.async_wait(boost::asio::posix::stream_descriptor::wait_read,
            boost::bind(&my_pipe::async_read, this, boost::asio::placeholders::error));
    } else {
        std::cout << "on_read error: " << ec.message() << "\n";
    }
}

int main()
{
    boost::asio::io_service ios;
    my_pipe obj(ios);
    ios.run();
}

Thanks for all your help. 感谢你的帮助。

A pipe is "widowed" when all handles on one end are closed. 当一端的所有手柄都关闭时,管道将“失效”。

In this case, after you get an EOF, you should close the pipe handle and then reopen the pipe. 在这种情况下,获得EOF后,应关闭管道手柄,然后重新打开管道。 You can then issue an async_read() on the new descriptor to wait for more data. 然后,您可以在新描述符上发出async_read()以等待更多数据。

If you have multiple writers, also consider that writes are only guaranteed to be atomic up to PIPE_BUF bytes. 如果您有多个编写器,还请考虑仅保证写操作是原子的,直到PIPE_BUF字节为止。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM