Asio的Buffer应该如何使用

文章目录

  • Asio的Buffer应该如何使用
    • 什么是asio::buffer
    • asio::const_buffer和asio::mutable_buffer
      • asio::mutable_buffer的设计
      • asio::const_buffer的设计
    • asio::buffer使用方法
    • 例子

什么是asio::buffer

asio::buffer并不是真正的缓冲区,想要获得缓冲区必须传入一段内存,比如st::vector<>,char[],std::string等。而asio::buffer负责管理这段内存,特别注意对于异步API内存在使用时必须有效。

asio::const_buffer和asio::mutable_buffer

  1. 构造函数不同
  2. const_buffer不可修改,初始化是什么使用socket发送时就会发送什么,比如使用st::vector初始化,虽然vector的内容可以修改,但是对asio::buffer来说不起作用

asio::mutable_buffer的设计

asio::mutable_buffer的设计不复杂,就是将缓冲区作为参数传进去;读写都由其它函数负责,asio::mutable_buffer本身只负责存储数据。

class mutable_buffer {public:/// Construct an empty buffer.mutable_buffer() BOOST_ASIO_NOEXCEPT:data_(0),size_(0) {}/// Construct a buffer to represent a given memory range.mutable_buffer(void* data, std::size_t size) BOOST_ASIO_NOEXCEPT:data_(data),size_(size) {}#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)mutable_buffer(void* data, std::size_t size,boost::asio::detail::function<void()> debug_check): data_(data),size_(size),debug_check_(debug_check) {}const boost::asio::detail::function<void()>& get_debug_check() const {return debug_check_;}
#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING/// Get a pointer to the beginning of the memory range.void* data() const BOOST_ASIO_NOEXCEPT {#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)if (size_ && debug_check_)debug_check_();
#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGINGreturn data_;}/// Get the size of the memory range.std::size_t size() const BOOST_ASIO_NOEXCEPT {return size_;}/// Move the start of the buffer by the specified number of bytes.mutable_buffer& operator+=(std::size_t n) BOOST_ASIO_NOEXCEPT{std::size_t offset = n < size_ ? n : size_;data_ = static_cast<char*>(data_) + offset;size_ -= offset;return *this;}private:void* data_;std::size_t size_;#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)boost::asio::detail::function<void()> debug_check_;
#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
};

asio::const_buffer的设计

与asio::mutable_buffer类似,同样只存储数据,但是不可更改。

class const_buffer {public:/// Construct an empty buffer.const_buffer() BOOST_ASIO_NOEXCEPT:data_(0),size_(0) {}/// Construct a buffer to represent a given memory range.const_buffer(const void* data, std::size_t size) BOOST_ASIO_NOEXCEPT:data_(data),size_(size) {}/// Construct a non-modifiable buffer from a modifiable one.const_buffer(const mutable_buffer& b) BOOST_ASIO_NOEXCEPT:data_(b.data()),size_(b.size())
#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING), debug_check_(b.get_debug_check())
#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING{}#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)const_buffer(const void* data, std::size_t size,boost::asio::detail::function<void()> debug_check): data_(data),size_(size),debug_check_(debug_check) {}const boost::asio::detail::function<void()>& get_debug_check() const {return debug_check_;}
#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING/// Get a pointer to the beginning of the memory range.const void* data() const BOOST_ASIO_NOEXCEPT {#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)if (size_ && debug_check_)debug_check_();
#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGINGreturn data_;}/// Get the size of the memory range.std::size_t size() const BOOST_ASIO_NOEXCEPT {return size_;}/// Move the start of the buffer by the specified number of bytes.const_buffer& operator+=(std::size_t n) BOOST_ASIO_NOEXCEPT{std::size_t offset = n < size_ ? n : size_;data_ = static_cast<const char*>(data_) + offset;size_ -= offset;return *this;}private:const void* data_;std::size_t size_;#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)boost::asio::detail::function<void()> debug_check_;
#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
};

asio::buffer使用方法

  1. 简单的方法就是在session类里申请一片内存(或全局内存),发送时使用asio::buffer包装
  2. BufferSequence
  3. 使用内存池

例子

  1. 在session类里申请一片内存

    class session: public std::enable_shared_from_this<session> {public:session(tcp::socket socket): socket_(std::move(socket)) {}~session() {}void start() {for (int i = 0; i < 100; ++i) {do_write();}}private:void do_write() {auto str = std::to_string(num);for (int i = 0; i < str.size(); ++i) {data[i] = str[i];}data[str.size()] = '\n';num++;//保证调用异步方法时session仍然存在auto self(shared_from_this());//使用boost::asio::buffer包装并发送boost::asio::async_write(socket_, boost::asio::buffer(data),[self](boost::system::error_code /*ec*/, std::size_t /*length*/) {});}// The socket used to communicate with the client.tcp::socket socket_;//固定大小缓冲区char data[128];int num = 0;
    };
    
  2. BufferSequence

    class shared_const_buffer
    {public:// Construct from a std::string.explicit shared_const_buffer(const std::string& data): data_(new std::vector<char>(data.begin(), data.end())),buffer_(boost::asio::buffer(*data_)){}// Implement the ConstBufferSequence requirements.typedef boost::asio::const_buffer value_type;typedef const boost::asio::const_buffer* const_iterator;const boost::asio::const_buffer* begin() const { return &buffer_; }const boost::asio::const_buffer* end() const { return &buffer_ + 1; }private:boost::shared_ptr<std::vector<char> > data_;//这里可以使用boost::asio::const_buffer数组//可以使用初始化列表初始化boost::asio::const_buffer buffer_;
    };class session: public std::enable_shared_from_this<session>
    {public:session(tcp::socket socket): socket_(std::move(socket)){}void start(){do_write();}private:void do_write(){std::time_t now = std::time(0);//初始化后不能更改,缺点就是对于变化的信息每次都要重新构造buffershared_const_buffer buffer(std::ctime(&now));auto self(shared_from_this());boost::asio::async_write(socket_, buffer,[self](boost::system::error_code /*ec*/, std::size_t /*length*/){});}// The socket used to communicate with the client.tcp::socket socket_;
    };
    
  3. 内存池

    内存池技术比较复杂了,也有不少开源实现,这里就不详述了

Asio的Buffer应该如何使用相关推荐

  1. 网上收集下boost::asio发送与传输相关的几个函数,老是忘记

    刚连接上:调用async_accept 1 boost::shared_ptr<tcp::socket> spMySocket(new tcp::socket(m_ioservice)); ...

  2. boost::asio译文

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

  3. Boost.Asio技术文档汇总

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

  4. boost::asio中文文档

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

  5. Boost.Asio技术文档

    文章来源:http://blog.csdn.net/henreash/article/details/7469707 Boost.Asio是一个跨平台的网络及底层IO的C++编程库,它使用现代C++手 ...

  6. Boost.Asio 技术文档

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

  7. 【Boost】boost库asio详解7——boost::asio::buffer用法

    1. asio::buffer常用的构造方法 asio::buffer有多种的构造方法,而且buffer大小是自动管理的 1.1 字符数组 [cpp] view plain copy  print? ...

  8. boost库学习④:boost::asio::buffer

    asio::buffer常用的构造方法 字符数组 char d1[128]; size_t bytes_transferred = socket.receive(boost::asio::buffer ...

  9. boost::asio使用UDP协议通信源码实现

    说明:以下源码来自参考文献[1], 比原文更丰富, 更有指导意义, 方便日后参考. udp servr端源码 //g++ -g udp_server.cpp -o udp_server -lboost ...

最新文章

  1. javascript 学习笔记之面向对象编程(二):继承多态
  2. 专家称中国***袭美是炒作
  3. LeetCode 965单值二叉树-简单
  4. c语言指针改良,重新认识C语言指针(上)(示例代码)
  5. Spring Boot基础学习笔记23:用户自定义授权管理
  6. 玩转 SpringBoot 2 快速搭建 | Spring Tool Suite篇
  7. 开花(在b数组中二分查找a数组元素)
  8. 内部文件检索——公司经验管理系统的一种有效方法
  9. Java从入门到精通 第18章 包及访问权限
  10. vigenere加密与解密算法
  11. ofo 深圳 java_[Android进阶]OFO首页实现小窥
  12. 来自太阳,爱情的故事,生存和欢乐的影子上升 - 免费节选
  13. 16G kingston U盘 解除写保护
  14. 喜马拉雅xm格式转化mp3_MTS视频格式转化
  15. UE4 关闭屏幕显示信息响应
  16. 二极管1N4148w
  17. php自助旅游网站平台
  18. UEFI 界面实例解析
  19. codeblocks的下载、安装与创建
  20. C语言编程题:分数的加减乘除

热门文章

  1. MySQL卸载不干净回不到初始安装页面(MySQL Connector Net卸载不了),重装报错Database initialization failed等问题解决办法
  2. [内附完整源码和文档] 基于Java的宾馆住宿管理系统
  3. zemax-01 衍射级次
  4. 课设 c语言编译学籍管理系统,C语言课设之学生学籍管理系统
  5. ddr老化测试_【鼎阳硬件智库原创︱DDR 】 DDR硬件调试篇:DDR硬件设计调试测试 之二...
  6. html5制作线路图,HTML5使用canvas画简单电路图
  7. ClearCase -- element is checked out reserved by another view解决办法
  8. Java(JCo3)与SAP系统相互调用
  9. ESXI安装CoreOS(第二版)
  10. mysql支持ASCII_MySQL ASCII()函数返回字符的ASCII码值