[C/C++后端开发学习]22 协议设计与Protobuf

文章目录

  • 通信协议设计
    • 基本要素
    • 消息帧完整性的判断方法
    • 主流序列化协议
  • Protobuf
    • 使用protobuf
      • IDL语法
        • 编译.proto
        • 命名规范
      • 在C++中使用protobuf
      • protobuf 编码

通信协议设计

基本要素

  • 要能完整地识别一帧数据(帧完整性)
  • 能够进行序列化和反序列化
  • 能够进行协议升级(包括客户端和服务端,需要指明协议版本)
  • 协议具备安全性(加解密)
  • 能够实现数据压缩,减小传输数据量

消息帧完整性的判断方法

  • 1、强制固定每个消息的数据长度,比如规定每个消息都发128字节
    这显然是很拙劣的方法。
  • 以特定符号来作为分界,如“\r\n”
    2、如果传输的消息中也带有这个符号就不可行了。
  • 3、固定消息头head+消息体结构body
    消息头的长度固定,其中带有指明消息数据长度的字段。先接收头部,解出这个消息完整⻓度,再按此⻓度接收消息体。

    是⽬前各种⽹络应⽤⽤的最多的⼀种消息格式

  • 4、字符流的头部+消息体,如HTTP协议和redis协议
    头部中有个字段存储消息总⻓度(content-length),根据特殊字符(⽐如\r\n或者\0)判断头部的完整性。由于不确定头部的长度,显然比第3种方法要麻烦一些。很多时候我们觉得HTTP协议简单只是因为我们对它比较熟悉罢了。

哪些场景适合使用HTTP协议:

  1. 对公⽹⽤户api,HTTP协议的穿透性最好,所以最适合;
  2. 效率要求没那么⾼的场景;
  3. 希望提供更多⼈熟悉的接⼝,⽐如新浪微博、腾讯提供的开放服务接⼝;

Protobuf就是基于方法3的。

主流序列化协议

类型 通信性 数据量 格式
XML 通用 重量级 文本(清晰易懂)
JSON 通用 轻量级 文本(方便调试)
Protobuf 独立 轻量级 二进制(高效)

序列化和反序列化性能对比:

  • 10万次序列化
    [C/C++后端开发学习]22 协议设计与Protobuf_第1张图片
  • 10万次反序列化
    [C/C++后端开发学习]22 协议设计与Protobuf_第2张图片

Protobuf

Protocol buffers 是⼀种语⾔中⽴、平台⽆关、可扩展的序列化数据的格式,只需使⽤ IDL(Interface description language,接⼝描述语⾔)对数据结构进⾏描述,就可以利⽤ Protocol buffers 的代码⽣成⼯具⽣成与序列化和反序列化相关的底层代码。

我们可以简单理解为:Protobuf根据 .proto 文件将一个类序列化为一个二进制串,然后通过API进行传输或存储。

使用protobuf

  1. 根据消息的结构编写.proto文件;
  2. ⽣成对应的.pb.cc和.pb.h⽂件。其中定义了消息的类,消息字段就是类成员,包含了设置和获取各个成员的方法;
  3. 在代码中使用这些类并编译:
    g++ -std=c++11 -o proto_test *.cc *.pb.cc -lprotobuf -lpthread

使用 libprotobuf 提供的API可以对消息类进行序列化和反序列化,如果消息的接收端没有描述该消息结构的 .proto 文件,拿到数据以后也无法解释成正常的数据。因此也可以认为 Protocol Buffer 比 JSON,XML 更安全一点点。

IDL语法

如何编写 .proto 文件请参考Language Guide (proto3)。

编译.proto

生成.pb.cc和.pb.h 文件的指令为:

protoc -I=input_dir --cpp_out=output_dir  *.proto

命名规范

message、枚举类型、服务名、方法名等均采用驼峰命名法,开头首字母大写命名。字段名采用下划线分隔法命名。

service ItemService {
  rpc GetSomething(ItemRequest) returns (ItemResponse);
}

message ItemServerRequest {
	required string item_name = 1;
	
	enum ItemType {
	  TYPE1_VALUE = 0;
	  TYPE2_VALUE = 1;
	}
}

在C++中使用protobuf

参考Protocol Buffer Basics: C++。

protobuf 编码

编码有助于对通过对序列化后的数据进行压缩。参考高效的数据压缩编码方式 Protobuf。

你可能感兴趣的:(C/C++后端开发学习笔记,c++,后端)