封装和解析类似json的  key-value 示例

{"ID" = 333,"name"="zds","3333"="ende"}

    msgpack::sbuffer sBuf;msgpack::packer<msgpack::sbuffer> pker(&sBuf);pker.pack_map(3);pker.pack(std::string("ID"));pker.pack(333);pker.pack(std::string("name"));pker.pack(std::string("zds"));pker.pack(std::string("333"));pker.pack(std::string("ende"));//unserilized
    msgpack::unpacked unpack;msgpack::unpack(unpack, sBuf.data(), sBuf.size());msgpack::object obj = unpack.get();std::cout << obj << std::endl;if (obj.type == msgpack::type::ARRAY)std::cout << "是array" << std::endl;else if (obj.type == msgpack::type::MAP)std::cout << "是map" << std::endl;if(obj.via.map.size > 0){auto pkv = obj.via.map.ptr;auto pkv_end = obj.via.map.ptr + obj.via.map.size;do {auto key = pkv->key;auto val = pkv->val;std::cout << "key:" << key << " value:" << val << std::endl;++pkv;} while (pkv < pkv_end);}

解析Socket示例

各类数据结构:

msgpack::object 他是一个引用,拷贝他的代价少,因为他是浅拷贝
msgpack::object_handle  他管理了一个对象的生命周期。他如果释放了,所有从他生成的object都是无效的引用

解析Socket示例

下列代码解析socke收包数据

unpacker.reserve_buffer 分配要收的数据的内存字节数
unpacker..buffer() 返回数据地址
unpacker.buffer_consumed() 设置实际收到的数据
unpacker.next(object_handle& oh) 循环解析数据

int main() {boost::asio::io_service ios;std::uint16_t const port = 12345;// Serverstd::size_t const window_size = 10;boost::asio::ip::tcp::acceptor ac(ios, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port));boost::asio::ip::tcp::socket ss(ios);std::function<void()> do_accept;std::function<void()> do_async_read_some;msgpack::unpacker unp;do_accept = [&] {ac.async_accept(ss,[&](boost::system::error_code const& e) {if (e) {std::cout << __LINE__ << ":" << e.message() << std::endl;return;}unp.reserve_buffer(window_size);do_async_read_some = [&] {ss.async_read_some(boost::asio::buffer(unp.buffer(), window_size),[&](boost::system::error_code const& e, std::size_t bytes_transferred) {if (e) {std::cout << __LINE__ << ":" << e.message() << std::endl;return;}std::cout << bytes_transferred << " bytes read." << std::endl;unp.buffer_consumed(bytes_transferred);msgpack::object_handle oh;while (unp.next(oh)) {std::cout << oh.get() << std::endl;// In order to finish the program,// return if one complete msgpack is processed.// In actual server, don't return here.return;}do_async_read_some();});};do_async_read_some();});};do_accept();// Clientauto host = "localhost";boost::asio::ip::tcp::resolver r(ios);boost::asio::ip::tcp::resolver::query q(host, boost::lexical_cast<std::string>(port));auto it = r.resolve(q);boost::asio::ip::tcp::socket cs(ios);boost::asio::async_connect(cs,it,[&](boost::system::error_code const& e, boost::asio::ip::tcp::resolver::iterator) {if (e) {std::cout << __LINE__ << ":" << e.message() << std::endl;return;}std::cout << __LINE__ << ":client connected" << std::endl;msgpack::sbuffer sb;msgpack::pack(sb, std::make_tuple(42, false, "hello world", 12.3456));write(cs, boost::asio::buffer(sb.data(), sb.size()));});// Start
    ios.run();
}

详解:

msgpack controls a buffer

msgpack provides a buffer management functionality named msgpack::unpacker. msgpack::unpacker is sutable for the following motivations:

  • msgpack data is chopped, and the client doesn't know when it will complete. This is a typical situation when you develop streaming applications.
  • You want to minimize copy opperations without careful memory management.

Here is the basic (not all) interface of msgpack::unpacker:

#ifndef MSGPACK_UNPACKER_INIT_BUFFER_SIZE
#define MSGPACK_UNPACKER_INIT_BUFFER_SIZE (64*1024)
#endif #ifndef MSGPACK_UNPACKER_RESERVE_SIZE #define MSGPACK_UNPACKER_RESERVE_SIZE (32*1024) #endif class unpacker { public: unpacker(unpack_reference_func f = &unpacker::default_reference_func, void* user_data = nullptr, std::size_t init_buffer_size = MSGPACK_UNPACKER_INIT_BUFFER_SIZE, unpack_limit const& limit = unpack_limit()); void reserve_buffer(std::size_t size = MSGPACK_UNPACKER_RESERVE_SIZE); char* buffer(); void buffer_consumed(std::size_t size); bool next(unpacked& result); };

Here is a basic pattern using msgpack::unpacker:

// The size may decided by receive performance, transmit layer's protocol and so on.
std::size_t const try_read_size = 100;msgpack::unpacker unp;// Message receive loop while (/* block until input becomes readable */) { unp.reserve_buffer(try_read_size); // unp has at least try_read_size buffer on this point. // input is a kind of I/O library object. // read message to msgpack::unpacker's internal buffer directly. std::size_t actual_read_size = input.readsome(unp.buffer(), try_read_size); // tell msgpack::unpacker actual consumed size. unp.buffer_consumed(actual_read_size); msgpack::unpacked result; // Message pack data loop while(unp.next(result)) { msgpack::object obj(result.get()); // Use obj } // All complete msgpack message is proccessed at this point, // then continue to read addtional message. }

msgpack::unpacker::next() returns true if one complete msgpack messege is proccessed. If msgpack message is correct but insufficient, it returns false. However, parsing proccess is proceeded and the context information is preserved in the msgpack::unpacker. It helps leveling the load of parse.

When msgpack message contains binary data, string data, or ext data, they are not copied but referenced from msgpack::object by default. See the following implementation:

inline bool unpacker::default_reference_func(type::object_type type, uint64_t len, void*)
{return true; }

You can also customize unpack_reference_func. Even if you use references, you don't need to control buffer's lifetime. The buffers' lifetime is controled by msgpack using msgpack::zone's finalizer_array and msgpack::unpacker's reference counting mechanism.

So, in most cases, the default behavior is enough. If you want to control the peak of memory consumption when receiving msgpack data patterns are predictable, customizing unpack_reference_func might be useful.

You can get a reference information from msgpack::unpacker::next() using the following function:

    bool next(unpacked& result, bool& referenced);

However, mostly you don't need to use that version of next() because referenced memories are managed by unpacker.

转载于:https://www.cnblogs.com/zhangdongsheng/p/7560928.html

MessagePack 学习笔记相关推荐

  1. PyTorch 学习笔记(六):PyTorch hook 和关于 PyTorch backward 过程的理解 call

    您的位置 首页 PyTorch 学习笔记系列 PyTorch 学习笔记(六):PyTorch hook 和关于 PyTorch backward 过程的理解 发布: 2017年8月4日 7,195阅读 ...

  2. 容器云原生DevOps学习笔记——第三期:从零搭建CI/CD系统标准化交付流程

    暑期实习期间,所在的技术中台-效能研发团队规划设计并结合公司开源协同实现符合DevOps理念的研发工具平台,实现研发过程自动化.标准化: 实习期间对DevOps的理解一直懵懵懂懂,最近观看了阿里专家带 ...

  3. 容器云原生DevOps学习笔记——第二期:如何快速高质量的应用容器化迁移

    暑期实习期间,所在的技术中台-效能研发团队规划设计并结合公司开源协同实现符合DevOps理念的研发工具平台,实现研发过程自动化.标准化: 实习期间对DevOps的理解一直懵懵懂懂,最近观看了阿里专家带 ...

  4. 2020年Yann Lecun深度学习笔记(下)

    2020年Yann Lecun深度学习笔记(下)

  5. 2020年Yann Lecun深度学习笔记(上)

    2020年Yann Lecun深度学习笔记(上)

  6. 知识图谱学习笔记(1)

    知识图谱学习笔记第一部分,包含RDF介绍,以及Jena RDF API使用 知识图谱的基石:RDF RDF(Resource Description Framework),即资源描述框架,其本质是一个 ...

  7. 计算机基础知识第十讲,计算机文化基础(第十讲)学习笔记

    计算机文化基础(第十讲)学习笔记 采样和量化PictureElement Pixel(像素)(链接: 采样的实质就是要用多少点(这个点我们叫像素)来描述一张图像,比如,一幅420x570的图像,就表示 ...

  8. Go 学习推荐 —(Go by example 中文版、Go 构建 Web 应用、Go 学习笔记、Golang常见错误、Go 语言四十二章经、Go 语言高级编程)

    Go by example 中文版 Go 构建 Web 应用 Go 学习笔记:无痕 Go 标准库中文文档 Golang开发新手常犯的50个错误 50 Shades of Go: Traps, Gotc ...

  9. MongoDB学习笔记(入门)

    MongoDB学习笔记(入门) 一.文档的注意事项: 1.  键值对是有序的,如:{ "name" : "stephen", "genda" ...

最新文章

  1. Hadoop通过路径和和链接访问HDFS
  2. word2010多级列表编号变成黑块的解决方案
  3. php mongo分页查询,PHP操作Mongodb之高级查询篇
  4. Spket在Eclipse/MyEclipse下的安装和配置(图文教程)
  5. 【Spring-AOP-学习笔记-3】@Before前向增强处理简单示例
  6. Valhalla项目:LW2内联类型的初步了解
  7. Linux | 高级I/O函数
  8. MathCAD求解方程组
  9. Sandy Bridge 12款双核心产品正式入列 Core i7-2620M Core i5-2540M
  10. Linux服务器开发环境搭建 Nginx+PHP+MongoDB
  11. eclipse 使用svn导入web项目
  12. Linux进阶之环境变量文件/etc/profile、/etc/bashrc、/etc/environment
  13. Android语言/国家代码清单
  14. Modebus - usb转RS485(芯片)串口驱动
  15. 华为usg6320服务器映射,华为防火墙USG6320配置(简单)
  16. 真实诈骗案例积累(一)
  17. 什么是 “use strict”; ? 使用它的好处和坏处分别是什么?
  18. FigDraw 22. SCI文章中绘图之核密度及山峦图 (ggridges)
  19. (1)学习ArduPilot代码库
  20. noip2003侦探推理详解

热门文章

  1. Scala模拟Spark分布式计算流程示例代码
  2. Scala中的二维数组乘法
  3. Linux date指令
  4. 网关层面为何要用Lua
  5. 桌面图标及文件夹图标选中后,图标一圈出现白色虚线解决方法
  6. php程序员必会的,PHP程序员必会的MySQL面试题
  7. uniapp保存图片_Uniapp实现保存图片到相册(封装起来)
  8. 如何将Felgo程序部署到Android中
  9. 计组第一章(唐朔飞)——计算机系统概述章节总结
  10. 从0到掌握Java泛型有这一篇博客就够了