ProtoBuf是Google开源的一套二进制流网络传输协议,它独立于语言,独立于平台。google 提供了多种语言的实现:java、c#、c++、Go 和Python,每一种实现都包含了相应语言的编译器以及库文件。由于它是一种二进制的格式,比使用 xml 进行数据交换快许多。可以把它用于分布式应用之间的数据通信或者异构环境下的数据交换。作为一种效率和兼容性都很优秀的二进制数据传输格式,可以用于诸如网络传输、配置文件、数据存储等诸多领域。
优点:传输效率快(比xml和json快10-20倍),文档型协议;
缺点:使用不太方便,仅是相对而言;
这里简单解释一下什么是文档型协议,向我们的xml和json一般在使用的时候都需要保存一份说明文档和一个实际的java类,而protobuf在使用的时候其定义的格式就是说明文档,简单明了而且可以将其编译成各个平台的类库,以java平台为例,其编程成jar之后,若定义文件发生了变化,则在使用jar包的话就会报错,必须重新编译,这也就保证了App端与服务器端的协议统一性。
基于前两篇对protobuf的介绍。如果嵌入式终端设备c语言,与后台前置通信,使用protobuf,能带来效率的提升吗?
举例,假如终端pos需要从后台采集前置下载票价,终端上传消费记录给采集前置posp。
传统的模式是采集前置定义好协议,然后终端和采集前置都按照协议一个一个来组包,收到数据后再按照协议一个一个来解包。
如果,按protobuf来做,会是什么样的呢?
同样采集前置和终端约定好*.proto文件。
通信协议简单了,定义为上送和下发proto文件的字节流。
收到之后,解析容易多了,因为直接就反序列化成对象了。直接取值即可。
记录上传,终端如果把记录存储为probuf格式的文件,在大小上并不会占用太多空间。
直接上送给前置,前置省略了解析的步骤。且中间避免了因对照协议解析的错误。
不用等待平台和采集一块联调,可以各自开始,因为 prptobuf 各个平台下都是通用的。
大大的提高了效率。
如果有机会,可以尝试尝试。但是这种尝试,需要采集和平台也接受这种技术,配合着才行。
最后介绍下简单使用:
linux平台下的使用,可以编译个工具,参见我的另一篇博客编译protobuf工具,或者网上能找个linux下能用的:protobuf在嵌入式linux下的移植及c语言调用_独行猫A 的沉淀、积累、总结。天天学习,好好向上...linux,Android,Vue,Go)-CSDN博客_protobuf 移植
Windows平台下使用,有很多现成的proto-c.exe程序工具,找一个能用的下载下来即可。
如可以在这下载:Releases · protocolbuffers/protobuf · GitHub
但是这些下载的不支持c语言的代码生成,仅支持c++,golang,java等语言的。要想c语言下使用,
参见我的另一篇博客编译protobuf工具。从GitHub - protobuf-c/protobuf-c: Protocol Buffers implementation in C 克隆下protobuf-c源码编译。
总结:
Google出品,必属精品。
1、经过测试,我们发现,其实protobuf的原理很简单,和两端都是C语言实现的client/server直接传输结构体变量原理是一样的,我们都知道,C语言结构体成员的存储方式都是顺序存储。所以发送和接收方都按照对应的成员排列位置进行解析,就可以实现数据的传输。
2、但是protobuf设计初衷应该是为了适应不同的语言之间数据传输,像java写的server里面就没有结构体,所以就不能传输C写的client里面的结构体变量给对方,对方是解析不了的。另外protobuf在.proto文件里面指定了具体的位置编号,否则应该就没办法生成.c和.h文件,如果后续双方通讯格式要做调整,双方都使用同一个修改后的.proto文件重新生产对应的源文件,重新编译即可。
3、为什么说用protobuf比json简单高效,原因就是你用json传输数据,每次字符串里面都传输了一堆没用的数据,比如键值对的冒号,以及键值名字和值的双引号,还有大小括号,因为通讯双方都知道对应的键值名以及怎么解析json(如果不知道键值名字,收到的数据还怎么解析?)。
双方都有的数据还每次传来传去,不是浪费是什么? 纯粹就是浪费带宽和存储,要传输的对方没有的数据,这才是有用数据。有人就说,这几个括号和键值名字能浪费多少带宽和空间,别小看这些小东西,假如数据交互量大和非常频繁,你就知道了,这里面的存储空间和带宽消耗差距是可怕惊人的。