boost.asio框架系列之buffer函数

 更新时间:2022年06月18日 15:44:45   作者:天方  
这篇文章介绍了boost.asio框架系列之buffer函数,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

创建buffer

在io操作中,对数据的读写大都是在一个缓冲区上进行的,在asio框架中,可以通过asio::buffer函数创建一个缓冲区来提供数据的读写。buffer函数本身并不申请内存,只是提供了一个对现有内存的封装。

char d1[128];
size_t bytes_transferred = sock.receive(asio::buffer(d1));

直接用字符串做buffer也是常见的形式:

string str = " hello world " ;
size_t bytes_transferred = sock.send(asio::buffer(str));

除了这些基础类型外,也可以使用stl中的容器,非常方便。

asio::buffer(std::vector<char>(128));
asio::buffer(std::array<char,128>());

将buffer还原为数据对象

前面的操作是通过把数据对象封装成buffer,在使用过程中往往也需要把buffer还原为数据对象。

char* p1 = asio::buffer_cast<char*>(buffer);

获取buffer大小

可以通过buffer_size函数获取buffer大小。

size_t s1 = asio::buffer_size(buf);

读写buffer

读写buffer一般都是和io对象相关联的,io对象成员函数中就提供了读写操作。以tcp::socket对象为例,它提供了read_some和write_some来实现读写操作:

std::array<char, 128> buf;
sock.read_some(asio::buffer(buf));

另外,asio名字空间下也提供了通用的read、write函数,通过它们可以实现更加高级的读写功能

size_t bytes_transfered = asio::read(sock, asio::buffer(buf), asio::transfer_all(), err);

这里我就使用了transfer_all标记强制读满buffer才返回,另外还有两个比较常用的标记transfer_at_least()和transfer_exactly(),非常方便。

streambuf

asio::streambuf则是提供了一个流类型的buffer,它自身是能申请内存的。它的好处是可以通过stl的stream相关函数实现缓冲区操作,处理起来更加方便。

    //通过streambuf发送数据
    asio::streambuf b;
    std::ostream os(&b);
    os << "Hello, World!\n";

    size_t n = sock.send(b.data());    // try sending some data in input sequence
    b.consume(n); // sent data is removed from input sequence

 

    //通过streambuf读数据
    asio::streambuf b;
    asio::streambuf::mutable_buffers_type bufs = b.prepare(512);    // reserve 512 bytes in output sequence
    size_t n = sock.receive(bufs);
    b.commit(n);    // received data is "committed" from output sequence to input sequence

    std::istream is(&b);
    std::string s;
    is >> s;

另外,asio名字空间下还提供了一个的read_until函数,可以实现读到满足指定条件的字符串为止,对于解析协议来说非常有用。

size_t n = asio::read_until(sock, stream, '\n');
asio::streambuf::const_buffers_type bufs = sb.data();
std::string line(asio::buffers_begin(bufs), asio::buffers_begin(bufs) + n);

这个指定条件除了是字符串外,还可以是正则表达式,非常给力。这也是asio库为什么要依赖于boost.regex的原因。(虽然regex已经标准化了,但仍得使用boost.regex库。等什么时候asio也标准化后估计就可以直接使用std.regex库了)

自定义内存分配

异步IO操作时往往会申请动态内存,使用完后就释放掉;在IO密集型的场景中,频繁的申请释放内存对性能会有较大影响。为了避免这个问题,asio提供了一个内存池式的模型 asio_handler_allocate 和 asio_handler_deallocate 来复用内存。

到此这篇关于boost.asio框架系列之buffer函数的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • C++中的枚举enum类型使用示例详解

    C++中的枚举enum类型使用示例详解

    枚举和类相似,能够定义一种新的数据类型,不同的是,枚举是将一组整形常量组织在一起,所以和类的使用方法有一些类似之处,这篇文章主要介绍了C++中的枚举enum类型使用示例详解,需要的朋友可以参考下
    2024-08-08
  • C语言简单实现快速排序

    C语言简单实现快速排序

    快速排序是一种不稳定排序,这篇文章主要为大家详细介绍了C语言简单实现快速排序,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-01-01
  • Java C++ 题解leetcode857雇佣K名工人最低成本vector pair

    Java C++ 题解leetcode857雇佣K名工人最低成本vector pair

    这篇文章主要为大家介绍了Java C++ 题解leetcode857雇佣K名工人最低成本vector pair示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • C语言数据结构不挂科指南之线性表详解

    C语言数据结构不挂科指南之线性表详解

    线性表是由 n(n≥0)个数据元素组成的有穷序列,这篇文章主要来和大家来了C语言数据结构中的线性表,感兴趣的小伙伴可以跟随小编一起了解一下
    2022-09-09
  • C++ Cmake的构建静态库和动态库详解

    C++ Cmake的构建静态库和动态库详解

    这篇文章主要为大家详细介绍了C++ Cmake的构建静态库和动态库,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03
  • C语言 八大排序算法的过程图解及实现代码

    C语言 八大排序算法的过程图解及实现代码

    排序是数据结构中很重要的一章,本文主要为大家介绍了常用的八个排序算法(插入,希尔,选择,堆排,冒泡,快排,归并,计数)的过程及代码实现,需要的朋友可以参考一下
    2021-12-12
  • C语言数据的存储专项分析

    C语言数据的存储专项分析

    使用编程语言进行编程时,需要用到各种变量来存储各种信息。变量保留的是它所存储的值的内存位置。这意味着,当您创建一个变量时,就会在内存中保留一些空间。您可能需要存储各种数据类型的信息,操作系统会根据变量的数据类型,来分配内存和决定在保留内存中存储什么
    2022-07-07
  • 初学C语言基本运算和表达式

    初学C语言基本运算和表达式

    在本文里小编给大家分享的是关于C语言基本运算和表达式的相关知识点,需要的朋友们跟着学习下。
    2019-08-08
  • 数组指针、指针数组以及二位数组的深入解析

    数组指针、指针数组以及二位数组的深入解析

    下面来讲讲多维数组与指针的关系。与普通数组一样,使用多维数组时,实际上将其自动转换为指向该数组第一个元素的指针
    2013-09-09
  • Qt中鼠标点击的几种状态

    Qt中鼠标点击的几种状态

    在Qt中,鼠标点击按钮通常会触发一系列的事件,包括pressed、released、clicked等,本文主要介绍了Qt中鼠标点击的几种状态,具有一定的参考价值,感兴趣的可以了解一下
    2023-12-12

最新评论