boost::asio::async_read 一直在命名管道上返回 eof
boost::asio::async_read keeps returning eof on named pipe
这是我在读取模式下打开管道的示例代码。它使用 boost::asio
从管道中读取。当数据(假设 X 字节)写入管道时,它调用 on_read
并在缓冲区中使用 ec=EOF
、bytes=X
和 X 字节数据。
发送 EOF 是因为写入器在完成写入管道后将其关闭。我想继续阅读。这就是为什么我在 on_read
中调用 pipe.async_wait()
。但是,即使没有准备好从管道中读取任何内容,on_read
也会调用 my_pipe::async_read()
,后者会再次用 bytes = 0
和 ec=EOF
调用 on_read()
。这在无限循环中进行。
为什么它一直在重复阅读 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();
}
感谢您的帮助。
当一端的所有手柄都关闭时,管道是"widowed"。
在这种情况下,在收到 EOF 后,您应该关闭管道句柄,然后重新打开管道。然后,您可以在新描述符上发出 async_read()
以等待更多数据。
如果您有多个写入器,还请考虑只保证原子写入最多 PIPE_BUF
个字节。
这是我在读取模式下打开管道的示例代码。它使用 boost::asio
从管道中读取。当数据(假设 X 字节)写入管道时,它调用 on_read
并在缓冲区中使用 ec=EOF
、bytes=X
和 X 字节数据。
发送 EOF 是因为写入器在完成写入管道后将其关闭。我想继续阅读。这就是为什么我在 on_read
中调用 pipe.async_wait()
。但是,即使没有准备好从管道中读取任何内容,on_read
也会调用 my_pipe::async_read()
,后者会再次用 bytes = 0
和 ec=EOF
调用 on_read()
。这在无限循环中进行。
为什么它一直在重复阅读 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();
}
感谢您的帮助。
当一端的所有手柄都关闭时,管道是"widowed"。
在这种情况下,在收到 EOF 后,您应该关闭管道句柄,然后重新打开管道。然后,您可以在新描述符上发出 async_read()
以等待更多数据。
如果您有多个写入器,还请考虑只保证原子写入最多 PIPE_BUF
个字节。