接前一篇文章:C++常用容器、函数、类集(12)
本文内容参考:
Boost AISO官方教程翻译版_boostasio中文教程-优快云博客
boost::asio译文 - DoubleLi - 博客园
特此致谢!
21. boost::asio::posix::stream_descriptor
(1)简介
boost::asio::posix::stream_descriptor是Boost.Asio库中用于处理POSIX风格的流式文件描述符(如管道、套接字、终端等)的一个类。这个类封装了底层的POSIX文件描述符操作,使得你可以在C++程序中使用非阻塞的I/O操作来与这些资源进行交互。
通过使用boost::asio::posix::stream_descriptor,你可以更方便地在C++中处理POSIX风格的I/O操作,同时享受到Boost.Asio提供的强大和灵活的异步编程模型。
很多Boost.Asio中的IO对象都是基于流的,包括:
boost::asio::ip::tcp::socket
boost::asio::ip::tcp::resolver
boost::asio::ip::tcp::acceptor
boost::asio::ssl::stream<>
boost::asio::windows::stream_handler
boost::asio::local::stream_protocol::socket
本地连接boost::asio::posix::stream_descriptor
面向流的文件描述符,比如stdout
,stdin
boost::asio::deadline_timer
定时器boost::asio::signal_set
信号处理
这意味着:
- 无消息边界。被传输的数据就是一个连续的字节序列。
- 读写操作可能会传递少量不需要的字节。这被称为短读或短写。
提供基于流IO操作模型的对象需要模拟如下几个操作:
- SyncReadStream
调用成员函数read_some()执行同步读操作。
- AsyncReadStream
调用成员函数async_read_some()执行异步读操作。
- SyncWriteStream
调用成员函数write_some()执行同步写操作。
- AsyncWriteStream
调用成员函数async_write_some()执行异步写操作。
(2)基于流的文件描述符
上边已提到,Boost.Asio包含在POSIX文件描述符上同步或异步读写的类,如管道、标准输入输出、各种设备(非常规文件)。例如,在标准输入输出上执行读写,需要创建如下对象:
posix::stream_descriptor in(my_io_service, ::dup(STDIN_FILENO));
posix::stream_descriptor out(my_io_service, ::dup(STDOUT_FILENO));
创建好之后,进行同步或异步读写流,即对象可用于read()、async_read()、write()、async_write()、read_until()、async_read_until()等函数。
(3)代码示例
1)异步写
#include <boost/asio/io_service.hpp>
#include <boost/asio/posix/stream_descriptor.hpp>
#include <boost/asio/write.hpp>
#include <boost/system/error_code.hpp>
#include <iostream>
#include <unistd.h>
using namespace boost::asio;
int main()
{
io_service ioservice;
posix::stream_descriptor stream{ioservice, STDOUT_FILENO};
auto handler = [](const boost::system::error_code&, std::size_t) {
std::cout << ", world!\n";
};
async_write(stream, buffer("Hello"), handler);
ioservice.run();
return 0;
}
Boost::asio::posix::stream_descriptor可以用一个文件描述符初始化,以启动对该文件描述符的异步操作。在本示例中,流链接到文件描述符STDOUT_FILENO以异步方式将字符串写入标准输出流。
2)异步读
#include <boost/asio.hpp>
#include <iostream>
#include <unistd.h> // 对于 POSIX 文件描述符操作
void read_handler(const boost::system::error_code& error, std::size_t bytes_transferred) {
if (!error) {
std::cout << "Received: " << std::string(boost::asio::buffer_cast<const char*>(buffer), bytes_transferred) << std::endl;
} else {
std::cerr << "Error: " << error.message() << std::endl;
}
}
int main() {
boost::asio::io_context io_context;
boost::asio::posix::stream_descriptor descriptor(io_context, ::dup(STDIN_FILENO)); // 使用 STDIN 的副本作为示例
boost::array<char, 128> buffer;
descriptor.async_read_some(boost::asio::buffer(buffer), read_handler);
io_context.run(); // 运行 io_context,以处理所有异步操作
return 0;
}
在本示例中:
1)首先,创建一个boost::asio::posix::stream_descriptor对象,传入io_context和一个 POSIX 文件描述符(例如通过dup获取的STDIN_FILENO);
2)然后,使用async_read_some方法来异步读取数据。这个方法接受一个缓冲区和一个回调函数,当数据准备好读取时,回调函数将被调用;
3)最后,通过io_context.run()启动事件循环,它处理所有排队的异步操作。
注意事项:
-
确保在调用io_context.run()前已经设置了所有异步操作。
-
处理错误和异常非常重要,尤其是在网络或文件 I/O 中。
-
使用完毕后,确保正确关闭文件描述符或清理资源。在示例中,由于使用了STDIN_FILENO的副本,因此通常不需要显式关闭文件描述符。但在其它情况下,可能需要使用close()。
更多内容请看下回。