简介

在网络编程中, 数据高效传输离不开数据的序列化. 直接编码不易于扩展, 而xml的方式太过于笨重, json的方式速度有点慢, protobuf是一个合理的方式, 把数据序列成二进制, 然后反序列化成原来的数据.

编译出protobuf文件

假设有一个msg.proto文件, 那么需要执行:

protoc msg.proto --cpp_out=./

当前目录会多出2个文件, 分别是msg.pb.hmsg.pb.cc, 这是编码解码的文件.

消息格式

使用protobuf3的语法格式, 结合数据嵌套, 最后要发送的是 FinalMsg数据.

syntax = "proto3";package Data;message Vector {int32 vx = 1;int32 vy = 2;int32 vz = 3;
}message Point {float px = 1;float py = 2;float pz = 3;
}enum MsgType {Vec = 0;Pnt = 1;
}message FinalMsg {string username = 1;string password = 2;MsgType msgtype = 3;Vector vector = 4;Point point = 5;
}

客户端

g++ 1.cpp -o 1 data.pb.cc -lprotobuf -pthread -lboost_system

代码:

#include <iostream>
#include <boost/asio.hpp>
#include <string>
#include "data.pb.h"std::string raw_ip_addr = "127.0.0.1";
unsigned short port_num = 6769;int main() {boost::asio::io_context ioc;boost::asio::ip::tcp::endpoint ep(boost::asio::ip::address::from_string(raw_ip_addr), port_num);boost::asio::ip::tcp::socket sock(ioc, ep.protocol());sock.connect(ep);Data::FinalMsg finalMsg;finalMsg.set_username(std::string("Tiger"));finalMsg.set_password(std::string("123456"));finalMsg.set_msgtype(Data::MsgType::Vec);auto vec = finalMsg.mutable_vector();vec->set_vx(1);vec->set_vy(2);vec->set_vz(3);auto pnt = finalMsg.mutable_point();pnt->set_px(1.1);pnt->set_py(2.5);pnt->set_pz(3.2);std::string msg;finalMsg.SerializeToString(&msg);if (boost::asio::write(sock, boost::asio::buffer(msg)) < 0) {std::cerr << "boost::asio::write() error\n";return -1;}std::cout << "send successfully\n";return 0;
}

服务器

g++ 2.cpp -o 2 data.pb.cc -lprotobuf -pthread -lboost_system
#include <iostream>
#include <string>
#include <boost/asio.hpp>
#include "data.pb.h"size_t SIZE = 1024;
unsigned short port_num = 6769;int main() {boost::asio::io_context ioc;boost::asio::ip::tcp::endpoint ep(boost::asio::ip::address_v4::any(), port_num);boost::asio::ip::tcp::acceptor acceptor(ioc, ep.protocol());acceptor.bind(ep);acceptor.listen(5);  // 最多排列5个boost::asio::ip::tcp::socket sock(ioc);acceptor.accept(sock);Data::FinalMsg finalMsg;std::string msg;boost::system::error_code error;try {char cmsg[SIZE];SIZE = boost::asio::read(sock, boost::asio::buffer(cmsg, SIZE), error);msg = std::move(std::string(cmsg, SIZE));if (error != boost::asio::error::eof) {throw boost::system::system_error(error);}finalMsg.ParseFromString(msg);  // 解析数据} catch (std::exception e) {std::cout << "recv error: " << e.what() << std::endl;sock.close();return -1;}sock.close();std::cout << "username: " << finalMsg.username() << std::endl;std::cout << "password:" << finalMsg.password() << std::endl;std::cout << "enum type: " << finalMsg.msgtype() << std::endl;auto vec = finalMsg.vector();auto pnt = finalMsg.point();std::cout << "vector, " << "x = " << vec.vx() << ", y = " << vec.vy() << ", z = " << vec.vz() << std::endl;std::cout << "point, " << "x = " << pnt.px() << ", y = " << pnt.py() << ", z = " << pnt.pz() << std::endl;return 0;
}

输出结果:

username: Tiger
password:123456
enum type: 0
vector, x = 1, y = 2, z = 3
point, x = 1.1, y = 2.5, z = 3.2

参考文档

  • https://developers.google.com/protocol-buffers/docs/cpptutorial
  • https://blog.csdn.net/K346K346/article/details/51754431

Protobuf的C++使用笔记相关推荐

  1. Protobuf学习笔记

    Protobuf学习笔记 Posted by iamxhuon 2012/05/22 Leave a comment (0)Go to comments Protocol buffers是什么? 首先 ...

  2. 冰冰学习笔记:简单了解protobuf

    欢迎各位大佬光临本文章!!! 还请各位大佬提出宝贵的意见,如发现文章错误请联系冰冰,冰冰一定会虚心接受,及时改正. 本系列文章为冰冰学习编程的学习笔记,如果对您也有帮助,还请各位大佬.帅哥.美女点点支 ...

  3. Go语学习笔记 - grpc server/client protobuf | 从零开始Go语言

    目录 创建Proto文件 生成proto文件对应的go文件 创建服务结构体 创建客户端测试 小结 学习笔记,写到哪是哪. 上一篇是写的redis操作来着,最近主要研究了一下grpc. 在玩grpc的过 ...

  4. protobufjs 命令执行_【原码笔记】-- protobuf.js 与 Long.js

    protobuf.js的结构和webpack的加载之后的结构很相似.这样的模块化组合是个不错的结构方式.1个是适应了不同的加载方式,2个模块直接很独立.webpack的功能更全一点.但如果自己封装js ...

  5. ProtoBuf使用笔记

    ProtoBuf 作为一种跨平台.语言无关.可扩展的序列化结构数据的方法,已广泛应用于网络数据交换及存储. 1. Proto定义 1.1. 说明 required表示该字段必须定义: optional ...

  6. protobuf java_ProtoBuf for java使用笔记 | 学步园

    三.新建项目ProtobufDemo.包名:com.protobufdemo.protobuf. 四.把上面的jar包跟exe放到工程目录下.新建文件夹:proto.在其下新建文件:msg.proto ...

  7. C++|Java工作笔记-google protobuf基本使用

    目录 前言 protoc生成 Java相关 C++相关 前言 这里主要是生成序列号,在我所做的项目中,一般是把数据序列化后扔到消息总线上,消费者读取了,自行解析. 个人感觉这种方式比Json和XML都 ...

  8. 【B站弹幕游戏开发笔记01】Win10系统下给Unity项目导入Protobuf

    Protobuf Github地址:https://github.com/protocolbuffers/protobuf 类库创建项目 使用vs2019 使用NuGet导入Google.Protob ...

  9. TLV文档阅读笔记-What is TLV及protobuf

    TLV的全称为tag-length-value,接地气的名字叫type-length-value. type:指数据的类型: length:指value的长度: value:为值 如下面这个TLV表示 ...

最新文章

  1. javascript中的for循环
  2. mac os vmware 显卡驱动_【新机】华为Mate 40系列国行售价明天公布,饿了么可以买手机?| 干翻牙膏厂,AMD发布RX6000显卡...
  3. 使用 Apache 工具类 HttpClients 进行 GET、POST请求
  4. linux停止tomcat为什么要kill其掉进程 而不是直接shutdown.sh
  5. 博弈论——战略式博弈
  6. 5. JavaScript RegExp 类型
  7. 给兆芯出主意:开发一批新指令,交叉授权
  8. 90后渐成互联网基金销售平台的购买主力
  9. 单片机 STC8H1K08-36I TSSOP20 - 低压检测
  10. 软件架构-事件驱动架构
  11. java基础 Day05 内部类、Object类、匿名内部类;方法的覆写;抽象类和接口
  12. flutter_engine 交叉编译【自定义编译器(最新)】
  13. VB 四言古诗词赏析 制作
  14. 详解浏览器缓存 前端开发必会
  15. 去噪算法 matlab,经典滤波算法去噪对比实验(Matlab实现)
  16. 毕设-基于LoRa的智能农业大棚(二)
  17. 51单片机真的过时了吗?单片机、ARM、DSP、FPGA/CPLD
  18. c++语言的设计与演化pdf,C++语言的设计和演化(高清)pdf
  19. 记录kafka consumer 消费失败
  20. macOS 必备软件之系统监控工具「iStat Menus」

热门文章

  1. mysql 空位补0_MySQL 删除数据后物理空间未释放
  2. 局部页面切换url为什么不变_python爬虫 - 翻页url不变网页的爬虫探究!
  3. linux mysql 5.0.45_linux 下安装mysql-5.0.45.tar.gz
  4. LeetCode 61. 旋转链表(python、c++)
  5. Anaconda下改变python的版本
  6. Java实验7 四、Java异常类(2)创建自己的日期错误异常类
  7. 自动驾驶——CenterNet(Objects as Points)的学习笔记
  8. 《南溪的目标检测学习笔记》——主干网络backbone设计的学习笔记
  9. [转]rsync命令中文文档
  10. 数据结构 (二) ----- 单向链表双向链表