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官方文档示例,或者网上的这篇文章。
就我个人而言,并不赞成在项目的前期就使用上这个allocator,毕竟这样带来了很大的代码复杂度。而是作为一个性能优化点,在后期性能优化的时候再试试用它有没有效果。并且内存池的也有很多不同的方案,google的google-perftools也值得一试。
FROM:http://www.cnblogs.com/TianFang/archive/2013/02/03/2890983.html
boost.asio系列——buffer的更多相关文章
- boost.asio系列——socket编程
asio的主要用途还是用于socket编程,本文就以一个tcp的daytimer服务为例简单的演示一下如何实现同步和异步的tcp socket编程. 客户端 客户端的代码如下: #include &l ...
- boost.asio系列——Timer
同步Timer asio中提供的timer名为deadline_timer,它提供了超时计时的功能.首先以一个最简单的同步Timer为例来演示如何使用它. #include<iostream&g ...
- boost.asio系列——io_service
IO模型 io_service对象是asio框架中的调度器,所有异步io事件都是通过它来分发处理的(io对象的构造函数中都需要传入一个io_service对象). asio::io_service i ...
- boost.asio系列(一)——deadline_timer
一.构造函数 一个deadline_timer只维护一个超时时间,一个deadline_timer不同时维护多个定时器.在构造deadline_timer时指定时间: basic_deadline_t ...
- boost::asio译文
Christopher Kohlhoff Copyright © 2003-2012 Christopher M. Kohlhoff 以Boost1.0的软件授权进行发布(见附带的LICENS ...
- Boost.Asio技术文档
Christopher Kohlhoff Copyright © 2003-2012 Christopher M. Kohlhoff 以Boost1.0的软件授权进行发布(见附带的LICENSE_1_ ...
- 客户端技术的一点思考(数据存储用SQLite, XMPP通讯用Gloox, Web交互用LibCurl, 数据打包用Protocol Buffer, socket通讯用boost asio)
今天看到CSDN上这么一篇< 彻底放弃没落的MFC,对新人的忠告!>, 作为一个一直在Windows上搞客户端开发的C++程序员,几年前也有过类似的隐忧(参见 落伍的感觉), 现在却有一些 ...
- boost.asio源码剖析(三) ---- 流程分析
* 常见流程分析之一(Tcp异步连接) 我们用一个简单的demo分析Tcp异步连接的流程: #include <iostream> #include <boost/asio.hpp& ...
- c++ boost asio库初学习
前些日子研究了一个c++的一个socket库,留下范例代码给以后自己参考. 同步server: // asio_server.cpp : コンソール アプリケーションのエントリ ポイントを定義します. ...
随机推荐
- 在线QQ客服
代码一: <a target="_blank" href="http://wpa.qq.com/msgrd?v=3&uin=451314789&si ...
- Spring IOC(DI)之注入方式
一次被问到IOC的注入方式,当时脑袋一阵混乱,不知道噻.于是google了一下,发现众说纷纭,有说三种的,有说四种的.都滚犊子吧,还是看看官方文档吧. DI exists in two major v ...
- wget -r -nc -np "http://www.zhihu.com/"
下载网站所有 -r, --recursive specify recursive download. -nc, --no-clobber skip dow ...
- MapReduce调度与执行原理之任务调度(续)
前言 :本文旨在理清在Hadoop中一个MapReduce作业(Job)在提交到框架后的整个生命周期过程,权作总结和日后参考,如有问题,请不吝赐教.本文不涉及Hadoop的架构设计,如有兴趣请参考相关 ...
- [置顶] T-sql sql server 设置主键约束、标示列、唯一约束、默认值、约束、创建表
----选择数据库 use ythome go ----查看表是否存在 if Exists ( select * from sysobjects where name='sys_menu' and t ...
- 客户机增加域 及server文件共享
客户机要增加域,右击我的电脑--属性--更改--域,输入域名.例:输入域名company.com中的company , 后面的com不要加. 再在弹出的窗体中输入域管理员的完整username(use ...
- C# ignoring letter case for if statement(Stackoverflow)
Question: I have this if statement: if (input == 'day') Console.Write({0}, dayData); When the user t ...
- 基于Zlib算法的流压缩、字符串压缩源码
原文:基于Zlib算法的流压缩.字符串压缩源码 Zlib.net官方源码demo中提供了压缩文件的源码算法.处于项目研发的需要,我需要对内存流进行压缩,由于zlib.net并无相关文字帮助只能自己看源 ...
- jQuery格式化时间插件formatDate
一.不传时间 $.formatDate("yyyy-MM-dd HH:mm:ss"); 二.传时间 $.formatDate("yyyy-MM-dd HH:mm:ss ...
- cocos2d-x游戏开发系列教程-坦克大战游戏之敌方坦克AI的编写
在上篇我们完成了子弹和地图碰撞的检测,在这篇我们将完成敌方坦克AI的编写. 具体思路是屏幕中保持有四个敌方坦克,然后坦克随机方向运动,并且子弹消失后1秒发射一次 1.我们新建一个敌方坦克的AI类来控制 ...