| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 网络协议 -> 使用ProtocolBuffer实现网络协议二进制格式 -> 正文阅读 |
|
[网络协议]使用ProtocolBuffer实现网络协议二进制格式 |
1.综述 这种做法存在一些问题。一是自定义的协议往往缺乏好的可扩展性,例如以后需要添加新字段,特别是字段要插入到以前字段的中间时,客户端和服务端协议解析代码得做相同修改。随着业务的发展,原先某些字段得删除时,协议解析代码又得修改,因此自定义协议解析在面对协议变化上因为需要重新编码因此会提升工作量降低效率,特别时代码的修改非常容易引入错误。 目前业内也有一些通用协议格式,例如jason, xml等,他们也存在一些问题。各种编程语言都有既定接口或模块之间解析这些格式,但是存在一个问题就是效率低下。当协议中的字段增多时,这些格式的解析耗时较长,我个人觉得这些格式存在一个不好使之处在于他们在发送二进制数据上。当协议字段对应字符串或是int这类长度较短的二进制数据时,他们的使用很方便,但如果使用他们传递图片内容能长度较长的二进制数据,那么我们需要进行base64编码后才方便将数据存储在这些格式中。 因此我们最好能找到一种可扩展性强,也就是协议格式能灵活的应对字段的删减而不必引入过多的代码修改;同时字段的查询效率高,二进制数据发送接收也方便的协议格式,那么就能大大提升我们制定网络协议的效率。 2.Protocol Buffer安装 2,接下来安装cmake程序,该程序的安装包也在给定百度盘共享目录下。 3,步骤1的命令会在对应目录下创建一个build目录并进入该目录,然后执行命令:
4,找到protobuf.sln,使用vs打开,在工程中有一个名为INSTALL的项目,选中它,右键选择“生成”编译protobuf可执行文件和对应的头文件和lib库。 5,完成后在路径上几层会生成一个install文件夹,里面会有编译好的结果,如图2所示: 图2 protobuf 编译结果。 3.Protocol Buffer使用方法
从图3可以看到,首先我们需要使用protocol buffer提供的语法来定义要使用的通信协议格式,它的语法不是编程语言,只是功能有限,特别用于描述数据结构的脚本语言,我们看个来自谷歌说明文档的具体例子:
} 从上面定义语言可以看出,protocol buffer用于定义二进制结构的语法跟编程语言非常像,其中message,required, optional, repeated都属于语法的关键字,string, enum, int32都属于字段的数据类型,这里需要提前说明的是,类似name=1;这种写法不是赋初值,一定要注意这点,这种写法的作用后面再解释。 message对应C语言中的struct关键字,它描述一块二进制内存中的字段分布情况。protocol buffer定义数据字段时能支持所有编程语言中使用到的数据类型,例如int, byte, string, float,double等,这里需要注意的是,如果我们想在协议中发送二进制数据串,那么对应类型就是bytes,当使用protocol buffer编译器将类似如上的二进制协议定义文件编译成c++代码时,bytes对应类型为string, 在java中则对应ByteString。 这里需要注意两个关键字,required表示在设置二进制协议字段时,required关键字修饰的字段必须要设置,如果你不设置但在代码中又去读取这些字段,那么代码就会抛出异常。而optional修饰的字段表示如果你不给该字段赋值,那么protocol buffer会自动帮你赋初值,例如int32类型会自动设置为0,string类型自动设置为空字符串等。如果不是非常必要,通常情况下我们使用optional修饰字段就比较灵活。 在上面例子中字段还可以赋初值,例如optional PhoneType type= 2 [default = HOME];它表示PhoneNumber中有一个字段名为type,它初始化值为2,也就是WORK,如果没有赋初值那么他就默认为HOME。 我们还能看到message可以间套,这就类似struct内部还能定义struct一样。同时关键字repeated对应编程语言的for,被该关键字修饰的字段可以重复0或多次。 前面强调过string name=1;后面的”=1“不是赋值,它是的作用是标签,我们可以认为这些数值是字段的牌号,在编译成二进制内容后protocol buffer知道如何去读取这些字段。 将上面描述的数据定义内容存储成以.proto为后缀的文件然后就可以使用protocol buffer将其编译成给定编程语言对应的代码文件,如图4所示: 图4命令执行后,在本地可以看到生成的对应语言的代码文件,如图5所示:
其中.cc和.h里面的代码提供了接口让我们读写.proto文件定义的数据结构,如果你打开.cc和.h文件查看可以发现里面代码非常复杂,因此我们千万不要去改动里面的内容要不然会造成难以理解的错误,我们只需要引用代码里面给出的接口来读写proto文件定义的协议数据结构即可。 对应每个字段,在.h中都定义了set和get接口,例如对应name字段它里面就有set_name这种接口让我们设置字段内容。对于被repeated关键字修饰的字段例如people,它还生成了people_size(),用户获取people字段中有多少个实例对象,如图6所示: 4.使用代码读写协议字段 图7 设置包含目录 2,在链接器->常规->附加库目录输入lib对应路径,如图8所示:
3,在连接器->输入->附加依赖项输入如图9所示内容:
4,在c/c++ ->代码生成->运行库,设置如图10所示: 图9 设置运行时库 void writeIntoPerson(example::Person& person, int id) {
} void ReadAddressBook(const example::AddressBook& address_book) { } int main()
} |
|
网络协议 最新文章 |
使用Easyswoole 搭建简单的Websoket服务 |
常见的数据通信方式有哪些? |
Openssl 1024bit RSA算法---公私钥获取和处 |
HTTPS协议的密钥交换流程 |
《小白WEB安全入门》03. 漏洞篇 |
HttpRunner4.x 安装与使用 |
2021-07-04 |
手写RPC学习笔记 |
K8S高可用版本部署 |
mySQL计算IP地址范围 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/25 17:53:29- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |