protobuf配置和使用

protobuf简介

Protocol Buffers(简称 Protobuf)是一种轻便高效的序列化数据结构的协议,由 Google 开发。它可以用于将结构化数据序列化到二进制格式,并广泛用于数据存储、通信协议、配置文件等领域。
我们的逻辑是有类等抽象数据构成的,而tcp是面向字节流的,我们需要将类结构序列化为字符串来传输。

下载protobuf安装包

官方下载地址
https://github.com/protocolbuffers/protobuf/releases

选择zip文件下载即可

https://cdn.llfc.club/1683799472011.jpg

因为官网下载速度较慢,我把下载好的protobuf存在网盘里了
https://pan.baidu.com/s/1Yg9Usdc3T-CYhyr9GiePCw?pwd=ng6x

验证码ng6x

下载完后解压即可,我放在D盘cppsoft文件夹下
https://cdn.llfc.club/1683800064977.jpg

下载cmake

CMake是一个跨平台的开源构建工具,可以用于自动化构建、测试和打包C++代码。与其他构建工具相比,CMake的优点之一是它的配置文件具有可读性和可维护性,而且支持多种编译器、操作系统和构建工具。

使用CMake,您可以将C++项目的配置和生成分离开来,从而使其更加可重复,并且可以在不同的平台上进行构建和测试。CMake使用类似于脚本语言的语法来描述构建过程,并生成适用于各种构建系统的构建文件(例如Makefile、Visual Studio解决方案等)。

以下是CMake的一些功能:

  • 自动生成包含目录、库和源文件列表的Makefile
  • 支持多种编译器和操作系统
  • 可以自动生成安装程序和打包文件
  • 跨平台支持
  • CMakeLists.txt 配置文件编写简单,易于维护

总之,CMake是一个强大的构建工具,可以大大简化C++项目的构建过程,并提高可移植性和可重复性。如果您正在寻找一个跨平台的自动构建工具来构建您的C++代码,请考虑使用CMake。

我们要在windows上生成protobuf对应的库,就需要用到cmake。
官方下载地址https://cmake.org/download/, 选择Windows Source下载。
由于官方下载较慢,可以去我的网盘下载
https://pan.baidu.com/s/1Yg9Usdc3T-CYhyr9GiePCw?pwd=ng6x

编译protobuf

在protobuf中创建一个文件夹,名字叫做visualstudio,你可以叫其他的名字,如下图
https://cdn.llfc.club/1684117823917.jpg
然后我们打开刚才下载的cmake桌面程序,点击后
source code 选择protobuf源码路径下的cmake目录
build binaries目录选择我们刚刚创建的visualstudio目录
生成选项可以依据自己要求生成。
https://cdn.llfc.club/1684118846421.jpg
点击config,再点击generate就可以生成了。
生成后我们可以看到protobuf的visualstudio文件夹内生成了.sln文件。
https://cdn.llfc.club/1684119115052.jpg
双击.sln文件,我的是默认用visual studio2019打开
https://cdn.llfc.club/1684119463529.jpg
可以单独选择libprotobuf编译,也可以选择All Build编译
编译时可以选择debug和release,建议每一个都编译一遍,这样就有debug和release两个版本的库了。
我选择的是X64位的debug模式编译,生成的库在visualstudio目录下的Debug文件夹里。
https://cdn.llfc.club/1684120169121.jpg
可以看到我们生成了protobuf相关的lib库和dll库,一个是静态类型的,一个是动态类型的。
接下来我创建一个新的文件夹D:\cppsoft\protoc
然后在该文件夹内创建一个bin文件夹(用来存储刚才protobuf生成的库)和include文件夹(用来存储protobuf的头文件)
https://cdn.llfc.club/1684121373828.jpg
将libprotobufd.lib和libprotocd.lib, 以及protoc.exe拷贝到bin目录下,当然为了偷懒,可以将刚才Debug目录下的所有内容都拷贝到bin目录也可以。
将protobuf文件夹下src文件夹里的google文件夹及其内容拷贝到protoc的include文件夹
将编译目录的google文件夹
https://cdn.llfc.club/1684121940871.jpg
拷贝到protoc的include文件夹
https://cdn.llfc.club/1684122265159.jpg
到此为止,我们protobuf的库生成工作就完成了。
因为我们要用到protoc命令,所以要将该命令配置到环境变量,在系统环境变量里添加一个环境变量PROTOBUF_HOME,
设置它的值为D:\cppsoft\protoc\bin
https://cdn.llfc.club/1684129895718.jpg
然后将该值添加到系统的path路径即可,格式为%PROTOBUF_HOME%
https://cdn.llfc.club/1684130311229.jpg
这样我们就可以直接使用protoc.exe了。

visual stuido配置protobuf

我们新建一个控制台项目,在项目属性中,配置选择Debug,平台选择X64,选择VC++目录,
在包含目录中添加 D:\cppsoft\protoc\include
在库目录中添加 D:\cppsoft\protoc\bin

在链接器的输入选项中添加protobuf用到的lib库

  1. libprotobufd.lib
  2. libprotocd.lib

到此,visual studio 的protobuf配置完毕。

生成pb文件

要想使用protobuf的序列化功能,需要生成pb文件,pb文件包含了我们要序列化的类信息。我们先创建一个msg.proto,该文件用来定义我们要发送的类信息

  1. syntax = "proto3";
  2. message Book
  3. {
  4. string name = 1;
  5. int32 pages = 2;
  6. float price = 3;
  7. }

这个文件定义了一个名为Book的消息类型,包含三个字段:name、pages和price。其中每个字段都有一个数字标识符,用于标识该字段在二进制流中的位置。
我们使用protoc.exe 基于msg.proto生成我们要用的C++类
在proto所在文件夹执行如下命令

  1. protoc --cpp_out=. ./msg.proto

—cpp_out= 表示指定要生成的pb文件所在的位置
./msg.proto 表示msg.proto所在的位置,因为我们是在msg.proto所在文件夹中执行的protoc命令,所以是当前路径即可。
执行后,会看到当前目录生成了msg.pb.h和msg.pb.cc两个文件,这两个文件就是我们要用到的头文件和cpp文件。
我们将这两个文件添加到项目里,然后在主函数中包含msg.pb.h,做如下测试

  1. #include <iostream>
  2. #include "msg.pb.h"
  3. int main()
  4. {
  5. Book book;
  6. book.set_name("CPP programing");
  7. book.set_pages(100);
  8. book.set_price(200);
  9. std::string bookstr;
  10. book.SerializeToString(&bookstr);
  11. std::cout << "serialize str is " << bookstr << std::endl;
  12. Book book2;
  13. book2.ParseFromString(bookstr);
  14. std::cout << "book2 name is " << book2.name() << " price is "
  15. << book2.price() << " pages is " << book2.pages() << std::endl;
  16. getchar();
  17. }

上面的demo中将book对象先序列化为字符串,再将字符串反序列化为book2对象。
这样就是visual studio 配置和使用protobuf的方法。

在网络中的应用

先为服务器定义一个用来通信的proto

  1. syntax = "proto3";
  2. message MsgData
  3. {
  4. int32 id = 1;
  5. string data = 2;
  6. }

id代表消息id,data代表消息内容
我们用protoc生成对应的pb.h和pb.cc文件
将proto,pb.cc,pb.h三个文件复制到我们之前的服务器项目里并且配置。

我们修改服务器接收数据和发送数据的逻辑
当服务器收到数据后,完成切包处理后,将信息反序列化为具体要使用的结构,打印相关的信息,然后再发送给客户端

  1. MsgData msgdata;
  2. std::string receive_data;
  3. msgdata.ParseFromString(std::string(_recv_msg_node->_data, _recv_msg_node->_total_len));
  4. std::cout << "recevie msg id is " << msgdata.id() << " msg data is " << msgdata.data() << endl;
  5. std::string return_str = "server has received msg, msg data is " + msgdata.data();
  6. MsgData msgreturn;
  7. msgreturn.set_id(msgdata.id());
  8. msgreturn.set_data(return_str);
  9. msgreturn.SerializeToString(&return_str);
  10. Send(return_str);

同样的道理,客户端在发送的时候也利用protobuf进行消息的序列化,然后发给服务器

  1. MsgData msgdata;
  2. msgdata.set_id(1001);
  3. msgdata.set_data("hello world");
  4. std::string request;
  5. msgdata.SerializeToString(&request);

总结

本文介绍了visual studio如何配置并使用protobuf,以及在服务器通信中的使用
源码链接https://gitee.com/secondtonone1/boostasio-learn

热门评论

热门文章

  1. 解密定时器的实现细节

    喜欢(566) 浏览(1793)
  2. C++ 类的继承封装和多态

    喜欢(588) 浏览(2500)
  3. slice介绍和使用

    喜欢(521) 浏览(1668)
  4. Linux环境搭建和编码

    喜欢(594) 浏览(5349)
  5. windows环境搭建和vscode配置

    喜欢(587) 浏览(1692)

最新评论

  1. 基于锁实现线程安全队列和栈容器 secondtonone1:我是博主,你认真学习的样子的很可爱,哈哈,我画的是链表由空变成1个的情况。其余情况和你思考的类似,只不过我用了一个无效节点表示tail的指向,最初head和tail指向的都是这个节点。
  2. 解决博客回复区被脚本注入的问题 secondtonone1:走到现在我忽然明白一个道理,无论工作也好生活也罢,最重要的是开心,即使一份安稳的工作不能给我带来事业上的积累也要合理的舍弃,所以我还是想去做喜欢的方向。
  3. 利用内存模型优化无锁栈 卡西莫多的礼物:感谢博主指点,好人一生平安o(* ̄▽ ̄*)ブ
  4. 类和对象 陈宇航:支持!!!!
  5. 泛型算法的定制操作 secondtonone1:lambda和bind是C11新增的利器,善于利用这两个机制可以极大地提升编程安全性和效率。

个人公众号

个人微信