C++常用容器、函数、类集(13)

接前一篇文章:C++常用容器、函数、类集(12)

 

本文内容参考:

Boost AISO官方教程翻译版_boostasio中文教程-优快云博客

boost::asio译文 - DoubleLi - 博客园

Boost.Asio的使用技巧-阿里云开发者社区

特此致谢!

 

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 面向流的文件描述符,比如stdoutstdin
  • 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()。

 

更多内容请看下回。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝天居士

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值