创建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官方文档示例,或者网上的这篇文章

就我个人而言,并不赞成在项目的前期就使用上这个allocator,毕竟这样带来了很大的代码复杂度。而是作为一个性能优化点,在后期性能优化的时候再试试用它有没有效果。并且内存池的也有很多不同的方案,google的google-perftools也值得一试。

FROM:http://www.cnblogs.com/TianFang/archive/2013/02/03/2890983.html

boost.asio系列——buffer的更多相关文章

  1. boost.asio系列——socket编程

    asio的主要用途还是用于socket编程,本文就以一个tcp的daytimer服务为例简单的演示一下如何实现同步和异步的tcp socket编程. 客户端 客户端的代码如下: #include &l ...

  2. boost.asio系列——Timer

    同步Timer asio中提供的timer名为deadline_timer,它提供了超时计时的功能.首先以一个最简单的同步Timer为例来演示如何使用它. #include<iostream&g ...

  3. boost.asio系列——io_service

    IO模型 io_service对象是asio框架中的调度器,所有异步io事件都是通过它来分发处理的(io对象的构造函数中都需要传入一个io_service对象). asio::io_service i ...

  4. boost.asio系列(一)——deadline_timer

    一.构造函数 一个deadline_timer只维护一个超时时间,一个deadline_timer不同时维护多个定时器.在构造deadline_timer时指定时间: basic_deadline_t ...

  5. boost::asio译文

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

  6. Boost.Asio技术文档

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

  7. 客户端技术的一点思考(数据存储用SQLite, XMPP通讯用Gloox, Web交互用LibCurl, 数据打包用Protocol Buffer, socket通讯用boost asio)

    今天看到CSDN上这么一篇< 彻底放弃没落的MFC,对新人的忠告!>, 作为一个一直在Windows上搞客户端开发的C++程序员,几年前也有过类似的隐忧(参见 落伍的感觉), 现在却有一些 ...

  8. boost.asio源码剖析(三) ---- 流程分析

    * 常见流程分析之一(Tcp异步连接) 我们用一个简单的demo分析Tcp异步连接的流程: #include <iostream> #include <boost/asio.hpp& ...

  9. c++ boost asio库初学习

    前些日子研究了一个c++的一个socket库,留下范例代码给以后自己参考. 同步server: // asio_server.cpp : コンソール アプリケーションのエントリ ポイントを定義します. ...

随机推荐

  1. 使用zabbix监控nginx

    在zabbix agentd客户端上,查看nginx是否加载了--with-http_stub_status_module.因为zabbix监控nginx是根据 nginx的Stub Status模块 ...

  2. Android 代码设置密码输入框内容的显示/隐藏

    //内容可见 mEtPassword.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); //内容不可见 m ...

  3. 让Solr返回JSON数据

    http://localhost:1985/solr/select/?q=*%3A*&version=2.2&start=0&rows=10&indent=on& ...

  4. JavaScript自调用匿名函数

    Self-Invoking Anonymous Function,即自调用匿名函数.顾名思义,该函数没有名称,不同的是,该函数定义后立即被调用.该函数的作用是在应用中初始化或做一次性工作. 普通匿名函 ...

  5. 采用sharedPreference保存数据

    1.sharedPreference保存数据 package com.example.login.service; import java.io.BufferedReader; import java ...

  6. 我的Python成长之路---第一天---Python基础(3)---2015年12月26日(雾霾)

    四.变量和常量 变量是用来存储程序运行期间需要临时保存可以不断改变的数据的标识符.Python有自身的内存回收机制,所以在开发过程中不用考虑变量的销毁等 Python中的变量名命名有如下规则: 1.变 ...

  7. Ajax的三种实现及JSON解析

    本文为学习笔记,属新手文章,欢迎指教!! 本文主要是比较三种实现Ajax的方式,为以后的学习开个头. 准备: 1.  prototype.js 2.  jquery1.3.2.min.js 3.  j ...

  8. CSS简介和CSS选择器

    <pre name="code" class="html">Css 简洁 css 选择器 标签选择器 类选择器 ID选择器 Css 层叠样式表 Ca ...

  9. cocos2d-x游戏开发系列教程-坦克大战游戏之敌方坦克AI的编写

    在上篇我们完成了子弹和地图碰撞的检测,在这篇我们将完成敌方坦克AI的编写. 具体思路是屏幕中保持有四个敌方坦克,然后坦克随机方向运动,并且子弹消失后1秒发射一次 1.我们新建一个敌方坦克的AI类来控制 ...

  10. Flex中怎么给表格中的滚动栏定位

    1.问题背景 假设表格中的字段过多,会出现滚动栏,在将滚动栏滚到一定的位置时,又一次刷新表格.滚动栏会回到原处,原来查看的字段还得继续滚动,才干查看到. 2.实现实例 <? xml versio ...