Buffers

从根本上说,I/O涉及在内存的连续区域(称为缓冲区)之间传递数据。这些缓冲区可以简单地表示为由一个指针和一个以字节为单位的大小组成的元组。为了能够高效地开发网络应用程序,Asio包括对分散-聚集操作(scatter-gather)的支持。这些操作涉及一个或多个缓冲区:

  • 分散-读(scatter-read)将数据接收到多个缓冲区中
  • 聚集-写(gather-write) 传输多个缓冲区

因此我们需要一个抽象来表示缓冲区的集合。Asio使用的方法是定义一个类型(实际是两个类型)来表示单个缓冲区。这些缓冲区可以存储在容器中以传递给分散-聚集操作。
除了将缓冲区指定为一个指针和一个以字节为单位的大小,Asio还区分了可修改内存(称为mutable)和不可修改内存(后者是从const变量存储中创建的)。这两个类型可以定义如下:

typedef std::pair<void*, std::size_t> mutable_buffer;
typedef std::pair<const void*, std::size_t> const_buffer;

一个mutable_buffer可以转换为const_buffer,反过来则无效。
但是Asio并不原样使用上述定义,而是定义了两个类:mutable_buffer 和 const_buffer。这些目标是为了提供连续内存的不透明表示,其中

  • 类型在转换中的行为类似于std::pair。也就是说,mutable_buffer可转换为const_buffer,但不允许进行相反的转换。
  • 具有防止内存区溢出的保护功能。给定一个缓冲区实例,用户只能创建另一个表示相同内存范围或其子范围的缓冲区。为了提供进一步的安全性,该库还包括从POD元素的array、boost::array、std::vector,或者std::string自动确定缓冲区大小的机制。
  • 使用data()成员函数显示访问底层内存。通常,应用程序永远不需要执行此操作,但库实现需要将原始内存传递给底层操作系统函数。

最后,通过将缓冲区对象放入容器中可以将多个缓冲区传递给分散-聚集操作(例如read()和write())。MutableBufferSequence 和 ConstBufferSequence 概念已经定义,因此可以使用诸如 std::vector、std::list、std::array 或 boost::array 之类的容器。

Streambuf for Integration with Iostreams

类 asio::basic_streambuf派生自std::basic_streambuf,用于将输入序列和输出序列与某个字符数组类型的一个或多个对象相关联,这些对象的元素存储任意值。这些字符数组对象是streambuf对象的内部对象,但提供了对数组元素的直接访问以允许它们与I/O操作(如socket的发送或接收操作)一起使用:

  • streambuf的输入序列可通过data()成员函数访问。此函数的返回类型满足ConstBufferSequence要求。
  • streambuf的输出序列可通过prepare()成员函数访问。此函数的返回类型满足MutableBufferSequence要求。
  • 通过调用commit()成员函数,数据从输出队列的头部传输到输入队列的尾部。
  • 通过调用consume()成员函数从输入队列的头部删除数据

streambuf构造函数接收一个size_t参数,该参数指定输入序列和输出序列的大小之和的最大值。任何操作如果使数据增长超过此限制将抛出std::length_error异常

Bytewise Traversal of Buffer Sequences

buffer_iterator<>类模板允许缓冲区序列(即满足MutableBufferSequence或ConstBufferSequence要求的类型)像连续的字节序列一样遍历。还提供了buffers_begin()和buffers_end()帮助函数,其中buffers_iterator<>模板参数是自动推导的。
例如,要从socket中读取一行到std::string,你可以这样写:

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

某些标准库实现(如 Microsoft Visual C++ 8.0 及更高版本附带的实现)提供了一项称为迭代器调试的功能。这意味着迭代器的有效性是在运行时检查的。如果程序尝试使用已失效的迭代器,则将触发断言。例如:

std::vector<int> v(1)
std::vector<int>::iterator i = v.begin();
v.clear(); // invalidates iterators
*i = 0; // assertion!

Asio 利用此功能添加缓冲区调试。请考虑以下代码:

void dont_do_this()
{std::string msg = "Hello, world!";asio::async_write(sock, asio::buffer(msg), my_handler);
}

调用异步读取或写入时,需要确保操作的缓冲区有效,直到调用完成处理程序。在上面的示例中,缓冲区是 std::string变量 msg。此变量位于栈上,因此在异步操作完成之前,它将超出范围。如果幸运的话,应用程序将崩溃,但随机故障的可能性更大。
启用缓冲区调试后,Asio 会将迭代器存储到字符串中,直到异步操作完成,然后解引用以检查其有效性。在上面的示例中,你将在 Asio 尝试调用完成处理程序之前观察到断言失败。
此功能在定义_GLIBCXX_DEBUG时自动可用于 Microsoft Visual Studio 8.0 或更高版本以及 GCC。此检查会产生性能成本,因此仅在调试版本中启用缓冲区调试。对于其他编译器,可以通过定义ASIO_ENABLE_BUFFER_DEBUGGING来启用它。也可以通过定义ASIO_DISABLE_BUFFER_DEBUGGING来显式禁用它。

原文:Buffers

Asio Buffers相关推荐

  1. ASIO 腾空出世 (那些年我们追过的网络库.PartII)

    ASIO 腾空出世 在地球最大的岛上,另一位少年开始拜读 ACE 的大作.那时候,没有 libuv 没有 libev 更没有 libevent . 有的只是 ACE. 然而这个南方小国的少年没有跟风陷 ...

  2. 网络库libevent、libev、libuv、libhv对比

    网络库libevent.libev.libuv对比_小麒麟的成长之路-CSDN博客_libevent libuv Libevent.libev.libuv三个网络库,都是c语言实现的异步事件库Asyn ...

  3. boost::asio译文

    boost::asio译文 Christopher Kohlhoff Copyright © 2003-2012 Christopher M. Kohlhoff 以Boost1.0的软件授权进行发布( ...

  4. Boost.Asio技术文档汇总

    Christopher Kohlhoff Copyright © 2003-2012 Christopher M. Kohlhoff 以Boost1.0的软件授权进行发布(见附带的LICENSE_1_ ...

  5. Boost Asio总结(15)class basic_stream_socket

    1. . 多种构造函数重载 一个参数:I/O服务 两个参数:1.I/O服务和协议:2.I/O服务和socket端点 . send()/receive()和write_some()/read_some( ...

  6. Boost Asio总结(9)数据缓冲区class mutable_buffer和const_buffer

    保存了一个void*的内存地址和数据长度. /// Holds a buffer that can be modified. class mutable_buffer {public:/// Cons ...

  7. 【Boost】boost库asio详解3——io_service作为work pool

    无论如何使用,都能感觉到使用boost.asio实现服务器,不仅是一件非常轻松的事,而且代码很漂亮,逻辑也相当清晰,这点上很不同于ACE. 使用io_service作为处理工作的work pool,可 ...

  8. 基于boost asio实现的支持ssl的通用socket框架

    情景分析    现已存在一个可用稳定的异步客户端类http_client_base,该类基于boost asio实现了连接服务器,发送请求,获取响应和解析http数据等操作,该类的大致实现框架如下   ...

  9. boost::asio向socket中异步读写数据

    内容代码参考自: Boost.Asio C++ Network Programming Cookbook 异步写入数据的核心是异步回调函数. 在此之前, 必须弄明白异步IO的基本概念和回调函数触发的时 ...

  10. Boost ASIO proactor 浅析

    Boost ASIO proactor 浅析 前情提要: Boost asio 的socket的异步非阻塞模式才有的是proactor模式,当IO操作介绍后回调相应的处理函数.ASIO在Linux平台 ...

最新文章

  1. apache日志分析
  2. 和为s的两个数字与和为s的连续正数序列
  3. 程序(进程)内存分布 解析
  4. vfifo控制mig_MIG IP控制DDR3读写测试
  5. 阿里云Elasticsearch -- 从0到1的云产品演进之路
  6. 安卓学习-界面-View的自定义
  7. Opportunity search in backend for status - some default system status
  8. 基于java百货中心供应链管理系统(含源文件)
  9. java写的教育管理的项目_干货分享|推荐12款适合做Java后台管理系统的项目
  10. Linux下套接字详解(四)----简单的TCP套接字应用(迭代型)
  11. TIDB介绍 新数据库趋势
  12. 测试Lock锁-可重入锁(Java)
  13. 华泰证券 python 自动交易软件_为何选用股票自动交易助手
  14. 机器学习大部分是用Python去实现,是否可以用Matlab去做机器学习呢?
  15. 全国人口年龄结构及抚养比(1987-2019年)
  16. 关于vue使用print.js打印会有一个空白页的问题
  17. php cmyk图片,php – 使用Imagick将图像从RGB转换为CMYK
  18. 卖主机的建辉互联张磊道貌岸然骗子公司(www.zzidc.top)
  19. 下载更多动态壁纸为莫哈韦沙漠,或使自己的
  20. HDLBits: 在线学习 SystemVerilog(十七)-Problem 106-114(移位寄存器)

热门文章

  1. C语言常见编译错误及分析
  2. ElK STACK的简要分析
  3. 探索性数据分析(四)——特征工程(对数转换、标准化/归一化、离散化、标签编码、独热编码、Dummy变量)
  4. 两向量叉乘的计算公式_向量的数量积和向量积怎么算?
  5. python做一个qq聊天窗口_python实现qq聊天(带界面)
  6. Hadoop HA 搭建
  7. python数据分析之爬虫七:爬取豆瓣书籍排行榜Top250
  8. 强力推荐一款游戏十分好玩
  9. chromium双核浏览器实现
  10. 清华计算机毕业论文,清华大学本科毕业论文