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函数的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 快速了解Boost.Asio 的多线程模型

    Boost.Asio 有两种支持多线程的方式,第一种方式比较简单:在多线程的场景下,每个线程都持有一个io_service,并且每个线程都调用各自的io_service的run()方法. 另一种支持多线程的方式:全局只分配一个io_service,并且让这个io_service在多个线程之间共享,每个线程都调用全局的io_service的run()方法. 每个线程一个 I/O Service 让我们先分析第一种方案:在多线程的场景下,每个线程都持有一个io_service (通常的做法是,让线程

  • boost.asio框架系列之调度器io_service

    IO模型 io_service对象是asio框架中的调度器,所有异步io事件都是通过它来分发处理的(io对象的构造函数中都需要传入一个io_service对象). asio::io_service io_service; asio::ip::tcp::socket socket(io_service); 在asio框架中,同步的io主要流程如下: 应用程序调用IO对象成员函数执行IO操作 IO对象向io_service 提出请求. io_service 调用操作系统的功能执行连接操作. 操作系统

  • C++ boost::asio编程-域名解析详细介绍

    C++ boost::asio编程-域名解析 在网络通信中通常我们并不直接使用IP地址,而是使用域名.这时候我们就需要用reslover类来通过域名获取IP,它可以实现 与IP版本无关的网址解析. #include "stdafx.h" #include "boost/asio.hpp" #include "boost/shared_ptr.hpp" #include "boost/thread.hpp" #include &

  • boost.asio框架系列之socket编程

    asio的主要用途还是用于socket编程,本文就以一个tcp的daytimer服务为例简单的演示一下如何实现同步和异步的tcp socket编程. 客户端 客户端的代码如下: #include <iostream> #include <boost/array.hpp> #include <boost/asio.hpp> using boost::asio::ip::tcp; int main(int argc, char* argv[]) { try { boost:

  • boost.asio框架系列之定时器Timer

    同步Timer asio中提供的timer名为deadline_timer,它提供了超时计时的功能.首先以一个最简单的同步Timer为例来演示如何使用它. #include <iostream> #include <boost/asio.hpp> int main() { boost::asio::io_service io; boost::asio::deadline_timer timer(io, boost::posix_time::seconds(3)); timer.wa

  • C++ boost::asio编程-异步TCP详解及实例代码

    C++ boost::asio编程-异步TCP 大家好,我是异步方式 和同步方式不同,我从来不花时间去等那些龟速的IO操作,我只是向系统说一声要做什么,然后就可以做其它事去了.如果系统完成了操作, 系统就会通过我之前给它的回调对象来通知我. 在ASIO库中,异步方式的函数或方法名称前面都有"async_ " 前缀,函数参数里会要求放一个回调函数(或仿函数).异步操作执行 后不管有没有完成都会立即返回,这时可以做一些其它事,直到回调函数(或仿函数)被调用,说明异步操作已经完成. 在ASI

  • C++ boost::asio编程-同步TCP详解及实例代码

    boost::asio编程-同步TCP boost.asio库是一个跨平台的网络及底层IO的C++编程库,它使用现代C++手法实现了统一的异步调用模型. boost.asio库支持TCP.UDP.ICMP通信协议. 下面介绍同步TCP模式: 大家好!我是同步方式! 我的主要特点就是执着!所有的操作都要完成或出错才会返回,不过偶的执着被大家称之为阻塞,实在是郁闷~~(场下一片嘘声),其实这样 也是有好处的,比如逻辑清晰,编程比较容易. 在服务器端,我会做个socket交给acceptor对象,让它

  • 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

  • C++基于boost asio实现sync tcp server通信流程详解

    目录 一.功能介绍 二.string类型数据交互 2.1 程序源码 2.2 编译&&执行 2.3 程序执行结果 三.byte类型数据交互 3.1 程序源码 3.2 编译&&执行 3.3 程序执行结果 一.功能介绍   基于boost asio实现server端通信,采用one by one的同步处理方式,并且设置连接等待超时.下面给出了string和byte两种数据类型的通信方式,可覆盖基本通信场景需求. 二.string类型数据交互   规定server与client双方

  • 实现PHP框架系列文章(6)mysql数据库方法

    实现一个mysql数据库封装需要考虑的问题 1.使用方便性 采用直接sql语句操作方式.只要会写sql语句,那么将没有其他学习成本. uctphp框架提供的dba辅助封装类,用会之后将爱不释手. 使用前需要显示初始化并连接到数据库吗,当然不需要. 直到执行第一条sql语句之前,都不会去连接数据库,甚至不会new一个db对象. dba将会在合适的时机去连接数据库并执行初始化字符编码操作. 查询语句.不需要new一个查询构造器也不提供链式操作方式,那样复杂且低效. dba提供了以下的查询辅助函数.

  • CI框架中数据库操作函数$this->db->where()相关用法总结

    本文实例总结了CI框架中数据库操作函数$this->db->where()相关用法.分享给大家供大家参考,具体如下: CI 框架数据库操作函数 this->db->where() 的使用 1) $this->db->where('MATCH (field) AGAINST ("value")', NULL, FALSE) 如果把$this->db->where() 接受可选的第三个参数设置为 FALSE, CodeIgniter 将不会为

随机推荐