使用 Boost Asio 异步等待文件描述符
我正在尝试将 D-Bus 与我的 boost::asio
应用程序集成.
I'm trying to integrate D-Bus with my boost::asio
application.
D-Bus 有一个 API,可以枚举一组要观察的 Unix 文件描述符(主要是套接字,但也可以是 FIFO).当这些描述符需要读取时,我应该通知 D-Bus API,以便它可以读取它们并执行操作.
D-Bus has an API that enumerates a set of Unix file descriptors (mainly sockets but could also be FIFOs) to be watched. When those descriptors have something to be read I should inform the D-Bus API so it can read them and do it's thing.
目前我正在这样做:
using boost::asio::posix::stream_descriptor;
void read_handle(stream_descriptor* desc, const boost::system::error_code& ec,
std::size_t bytes_read)
{
if (!ec) {
stream_descriptor::bytes_readable command(true);
descriptor->io_control(command);
std::size_t bytes_readable = command.get();
std::cout << "It thinks I should read" << bytes_readable
<< " bytes" << std::endl;
} else {
std::cout << "There was an error" << std::endl;
}
}
void watch_descriptor(boost::asio::io_service& ios, int file_descriptor)
{
// Create the asio representation of the descriptor
stream_descriptor* desc = new stream_descriptor(ios);
desc->assign(file_descriptor);
// Try to read 0 bytes just to be informed that there is something to be read
std::vector<char> buffer(0);
desc->async_read_some(boost::asio::buffer(buffer, 0),
boost::bind(read_handle, desc, _1, _2));
}
但是立即调用处理程序说它有 0 个字节要读取.我希望只有在有东西要读取时才调用它,但是 boost::asio 不能 读取它.它应该像一个美化的 select()
.有没有简单的方法可以做到这一点?
But the handler is called right away saying that it has 0 bytes to be read. I would like it to be called only when there is something to be read, but boost::asio CAN NOT read it. It should act just as a glorified select()
. Is there a simple way to do that?
PS:我在我的软件中广泛使用了 boost::asio
,这只是其中的一小部分,所以我不想依赖 glib
或其他主循环.
PS: I'm extensively using boost::asio
in my software, this is just a small part of it, so I would like not to depend on glib
or other mainloops.
推荐答案
这正是问题所在 null_buffers 是设计的 为.
This is precisely the problem null_buffers was designed for.
有时必须集成一个程序与想要的第三方库执行 I/O 操作本身.为了促进这一点,Boost.Asio包括一个 null_buffers 类型,可以与读和写一起使用操作.null_buffers 操作直到 I/O 对象出现时才返回准备好"执行操作.
Sometimes a program must be integrated with a third-party library that wants to perform the I/O operations itself. To facilitate this, Boost.Asio includes a null_buffers type that can be used with both read and write operations. A null_buffers operation doesn't return until the I/O object is "ready" to perform the operation.
例如,执行一个非阻塞读取类似可以使用以下内容:
As an example, to perform a non-blocking read something like the following may be used:
ip::tcp::socket socket(my_io_service);
...
ip::tcp::socket::non_blocking nb(true);
socket.io_control(nb);
...
socket.async_read_some(null_buffers(), read_handler);
...
void read_handler(boost::system::error_code ec)
{
if (!ec)
{
std::vector<char> buf(socket.available());
socket.read_some(buffer(buf));
}
}
还有一个优秀示例文档.
相关文章