【ProtoBuf】通讯录实现(网络版)

Protobuf 还常用于通讯协议、服务端数据交换场景。那么在这个示例中,我们将实现一个网络版本的通讯录,模拟实现客户端与服务端的交互,通过 Protobuf 来实现各端之间的协议序列化。

需求如下:

  • 客户端可以选择对通讯录进行以下操作:
  1. 新增⼀个联系人
  2. 删除⼀个联系人
  3. 查询通讯录列表
  4. 查询⼀个联系人的详细信息
  • 服务端提供增、删、查能力,并需要持久化通讯录。
  • 客户端、服务端间的交互数据使用 Protobuf 来完成。


一、环境搭建

Httplib 库:cpp-httplib 是个开源的库,是一个 C++ 封装的 http 库,使用这个库可以在 Linux、Windows 平台下完成 http 客户端、http 服务端的搭建。使用起来非常方便,只需要包含头文件 httplib.h 即可。编译程序时,需要带上 -lpthread 选项。

源码库地址:

yhirose/cpp-httplib: A C++ header-only HTTP/HTTPS server and client library (github.com)


二、Centos 下编写的注意事项

如果使用 CentOS 环境,yum 源带的 g++ 最新版本是 4.8.5,发布于 2015 年,年代久远。编译该项目会出现异常,将 gcc / g++ 升级为更高版本可解决问题。

# 安装scl
yum install -y centos-release-scl

# 安装gcc 8版本
yum install -y devtoolset-8-gcc devtoolset-8-gcc-c++

# 启⽤版本
source /opt/rh/devtoolset-8/enable

# 查看版本已经变成gcc 8.3.1
gcc -v

第二步安装 gcc 8 版本的时候,如果显示如下报错:

Could not retrieve mirrorlist http://mirrorlist.centos.org/

可以参考:

SCL更换阿里数据源_centos-sclo-scl-rh.repo-CSDN博客

注意 scl 命令启用只是临时的,退出 shell 或重启就会恢复原系统 gcc 版本,如果要长期使用的话执行:

echo "source /opt/rh/devtoolset-8/enable" >> /etc/profile

三、约定双端交互接口

1、新增一个联系人

[请求] 
    Post /contacts/add AddContactRequest
    Content-Type: application/protobuf

[响应] 
    AddContactResponse 
    Content-Type: application/protobuf

2、删除一个联系人

[请求] 
    Post /contacts/del DelContactRequest 
    Content-Type: application/protobuf

[响应] 
    DelContactResponse 
    Content-Type: application/protobuf

3、查询通讯录列表

[请求]
    GET /contacts/find-all 
 
[响应] 
    FindAllContactsResponse 
    Content-Type: application/protobuf

4、查询一个联系人的详细信息

[请求] 
    Post /contacts/find-one FindOneContactRequest 
    Content-Type: application/protobuf
 
[响应]
    FindOneContactResponse 
    Content-Type: application/protobuf

四、客户端代码实现

1、add_contact.proto


2、main.cc


3、ContactException.h(定义异常类)


4、makefile


5、运行结果


五、服务端代码实现

1、add_contact.proto(服务端存储通讯录结构定义)


2、main.cc


3、makefile


4、运行结果


六、总

1、序列化能力对比验证

分别使用 PB 与 JSON 的序列化与反序列化能力, 对值完全相同的一份结构化数据进行不同次数的性能测试。为了可读性,下面这一份文本使用 JSON 格式展示了需要被进行测试的结构化数据内容:

{
    "age" : 20,
    "name" : "张珊",
    "phone" : 
    [
        {
            "number" : "110112119",
            "type" : 0
        },
        {
            "number" : "110112119",
            "type" : 0
        },
        {
            "number" : "110112119",
            "type" : 0
        },
        {
            "number" : "110112119",
            "type" : 0
        },
        {
            "number" : "110112119",
            "type" : 0
        }
    ],
    "qq" : "95991122",
    "address" : 
    {
        "home_address" : "陕西省西安市⻓安区",
        "unit_address" : "陕西省西安市雁塔区"
    },
    "remark" : 
    {
        "key1" : "value1",
        "key2" : "value2",
        "key3" : "value3",
        "key4" : "value4",
        "key5" : "value5"
    }
}

开始进行测试代码编写,我们在新的目录下新建 contacts.proto 文件,内容如下:

使用 protoc 命令编译文件后,新建性能测试文件 compare.cc,我们分别对相同的结构化数据进行 100、100010000100000 次的序列化与反序列化,分别获取其耗时与序列化后的大小。内容如下:

Makefile:

测试结果如下:

由实验结果可得:

  • 编解码性能:ProtoBuf 的编码解码性能,比 JSON 高出 2-4 倍。
  • 内存占用:ProtoBuf 的内存 278,而 JSON 到达 567,ProtoBuf 的内存占用只有 JSON 的 1/2。

注意:以上结论的数据只是根据该项实验得出。因为受不同的字段类型、字段个数等影响,测出的数据会有所差异。

该实验有很多可待优化的地方。但其实这种粗略的测试,也能从其中看出 ProtoBuf 的优势。


2、总结

  • XML、JSON、ProtoBuf 都具有数据结构化和数据序列化的能力。
  • XML、JSON 更注重数据结构化,关注可读性和语义表达能力。ProtoBuf 更注重数据序列化,关注效率、空间、速度,可读性差,语义表达能力不足,为保证极致的效率,会舍弃⼀部分元信息。
  • ProtoBuf 的应用场景更为明确,XML、JSON 的应用场景更为丰富。

相关推荐

  1. 通讯录实现

    2024-07-19 20:14:04       57 阅读
  2. <span style='color:red;'>protobuf</span>

    protobuf

    2024-07-19 20:14:04      48 阅读
  3. 网络数据通信—ProtoBuf实现序列化和反序列化

    2024-07-19 20:14:04       54 阅读
  4. C语言——通讯录实现

    2024-07-19 20:14:04       26 阅读
  5. 实现通讯录(顺序表)

    2024-07-19 20:14:04       25 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-19 20:14:04       70 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-19 20:14:04       74 阅读
  3. 在Django里面运行非项目文件

    2024-07-19 20:14:04       62 阅读
  4. Python语言-面向对象

    2024-07-19 20:14:04       72 阅读

热门阅读

  1. MySql的运用

    2024-07-19 20:14:04       20 阅读
  2. 使用 tcpdump 进行网络流量捕获与分析

    2024-07-19 20:14:04       20 阅读
  3. 挂马病毒是什么

    2024-07-19 20:14:04       19 阅读
  4. 深入理解并使用 MySQL 的 SUBSTRING_INDEX 函数

    2024-07-19 20:14:04       20 阅读
  5. 【无标题】

    2024-07-19 20:14:04       21 阅读
  6. z-fighting多视锥方案缺失depth information的思考

    2024-07-19 20:14:04       15 阅读
  7. 代码随想录打卡第二十九天

    2024-07-19 20:14:04       19 阅读
  8. 产品经理的样板

    2024-07-19 20:14:04       14 阅读
  9. 关于二进制和八进制

    2024-07-19 20:14:04       18 阅读
  10. Linux 和 Unix 系统中非常流行文本处理工具awk

    2024-07-19 20:14:04       16 阅读
  11. 专升本-1.0.4(英语)-升本208天-学习成果展示

    2024-07-19 20:14:04       18 阅读
  12. 1818:ATP

    2024-07-19 20:14:04       21 阅读
  13. 使用容器化技术部署淘客返利系统的实践与挑战

    2024-07-19 20:14:04       20 阅读
  14. 【WiFi】DFS Vs ZW-DFS

    2024-07-19 20:14:04       17 阅读