protobuf-c 在arm linux 嵌入式平台的使用 protobuf和Json对比测试
2017-04-27 21:49
871 查看
关于什么是protobuf,网上搜搜一大堆,很多人用的都还是json,以为json是多种语言传输数据是万能的,看完了protobuf的实现,就明白了简单高效才是王道。
1、首先写一个.proto扩展名的文件json.proto,内容格式如下
message response
{
required uint32 led_on=1;
required string node_id=2;
required string parent_id=3;
required string uuid=4;
}
2、执行命令生成.c和.h文件,protoc-c可执行文件已经预先生成了,编译protobuf-c参考http://blog.csdn.net/code_style/article/details/54375785
./protoc-c json.proto
3、写示例代码main.c:
解析:protobuf的核心就是pack和unpack以及最后的free_unpack,比如客户端要给服务端发送一个msg,客户端把pack好的pBuf缓冲区数据直接发出去,服务端收到数据之后,再从pBuf里面“取出”out结构体指针指向的msg,最后调用free_unpacked释放out就可以了。
4、编译注意事项
注意相关头文件所在目录为./protobuf-c/protobuf-c.h,相关libprotobuf-c.so库文件所在路径为./protobuf-c-arm/lib
5、编译,最终生成main可执行文件,将main放在开发板上,注意,相关的libc库和libprotobuf-c.so链接库都放在了开发板上/usr/arm-linux-gnueabi/lib目录下,否则运行是找不到.so库的
arm-linux-gnueabi-gcc main.c -o main json.pb-c.c -I./ -lprotobuf-c -L./protobuf-c-arm/lib -Wl,-rpath,/usr/arm-linux-gnueabi/lib
6、运行./main
实现了msg消息发送给out输出,同样类型的消息,Json需要91个字节,protobuf只需要49个字节,其实json里面的键值对name是完全不需要传输的,因为通讯双方都知道对应的name,只需要传输的只是value,但是每次传输数据,都要把name都传来传去,消耗了大量的带宽和数据存储空间
下面是测试结果
附录:
1、经过测试,我们发现,其实protobuf的原理很简单,和两端都是C语言实现的client/server直接传输结构体变量原理是一样的,我们都知道,C语言结构体成员的存储方式都是顺序存储。所以发送和接收方都按照对应的成员排列位置进行解析,就可以实现数据的传输。
2、但是protobuf设计初衷应该是为了适应不同的语言之间数据传输,像java写的server里面就没有结构体,所以就不能传输C写的client里面的结构体变量给对方,对方是解析不了的。另外protobuf在.proto文件里面指定了具体的位置编号,否则应该就没办法生成.c和.h文件,如果后续双方通讯格式要做调整,双方都使用同一个修改后的.proto文件重新生产对应的源文件,重新编译即可。
3、为什么说用protobuf比json简单高效,原因就是你用json传输数据,每次字符串里面都传输了一堆没用的数据,比如键值对的冒号,以及键值名字和值的双引号,还有大小括号,因为通讯双方都知道对应的键值名以及怎么解析json(如果不知道键值名字,收到的数据还怎么解析?)。
双方都有的数据还每次传来传去,不是浪费是什么? 纯粹就是浪费带宽和存储,要传输的对方没有的数据,这才是有用数据。有人就说,这几个括号和键值名字能浪费多少带宽和空间,别小看这些小东西,假如数据交互量大和非常频繁,你就知道了,这里面的存储空间和带宽消耗差距是可怕惊人的。
4、最后不得不佩服,google出品必属精品。
1、首先写一个.proto扩展名的文件json.proto,内容格式如下
message response
{
required uint32 led_on=1;
required string node_id=2;
required string parent_id=3;
required string uuid=4;
}
2、执行命令生成.c和.h文件,protoc-c可执行文件已经预先生成了,编译protobuf-c参考http://blog.csdn.net/code_style/article/details/54375785
./protoc-c json.proto
3、写示例代码main.c:
解析:protobuf的核心就是pack和unpack以及最后的free_unpack,比如客户端要给服务端发送一个msg,客户端把pack好的pBuf缓冲区数据直接发出去,服务端收到数据之后,再从pBuf里面“取出”out结构体指针指向的msg,最后调用free_unpacked释放out就可以了。
//main.c #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include "json.pb-c.h" int main(void) { Response msg,*out; unsigned char *pBuf; unsigned int Len; response__init(&msg); //init default msg.led_on=1; msg.node_id="5149013220584027"; msg.parent_id="5149013108519750"; msg.uuid="121212121"; Len=response__get_packed_size(&msg); printf("msg pack size %d\n",Len); pBuf=malloc(Len); if(pBuf) { response__pack(&msg,pBuf); //construct msg to pBuf FILE *fp =fopen("protobuf.txt","wb+"); //output raw if(fp) { fwrite(pBuf,Len,1,fp); fclose(fp); fp=NULL; } out=response__unpack(NULL,Len,pBuf); if(out) { printf("out->led_on=%d\n",((Response*)out)->led_on); printf("out->node_id=%s\n",((Response*)out)->node_id); printf("out->parent_id=%s\n",((Response*)out)->parent_id); printf("out->uuid=%s\n",((Response*)out)->uuid); response__free_unpacked(out,NULL); } } printf("End\n"); }
4、编译注意事项
注意相关头文件所在目录为./protobuf-c/protobuf-c.h,相关libprotobuf-c.so库文件所在路径为./protobuf-c-arm/lib
5、编译,最终生成main可执行文件,将main放在开发板上,注意,相关的libc库和libprotobuf-c.so链接库都放在了开发板上/usr/arm-linux-gnueabi/lib目录下,否则运行是找不到.so库的
arm-linux-gnueabi-gcc main.c -o main json.pb-c.c -I./ -lprotobuf-c -L./protobuf-c-arm/lib -Wl,-rpath,/usr/arm-linux-gnueabi/lib
6、运行./main
实现了msg消息发送给out输出,同样类型的消息,Json需要91个字节,protobuf只需要49个字节,其实json里面的键值对name是完全不需要传输的,因为通讯双方都知道对应的name,只需要传输的只是value,但是每次传输数据,都要把name都传来传去,消耗了大量的带宽和数据存储空间
下面是测试结果
附录:
1、经过测试,我们发现,其实protobuf的原理很简单,和两端都是C语言实现的client/server直接传输结构体变量原理是一样的,我们都知道,C语言结构体成员的存储方式都是顺序存储。所以发送和接收方都按照对应的成员排列位置进行解析,就可以实现数据的传输。
2、但是protobuf设计初衷应该是为了适应不同的语言之间数据传输,像java写的server里面就没有结构体,所以就不能传输C写的client里面的结构体变量给对方,对方是解析不了的。另外protobuf在.proto文件里面指定了具体的位置编号,否则应该就没办法生成.c和.h文件,如果后续双方通讯格式要做调整,双方都使用同一个修改后的.proto文件重新生产对应的源文件,重新编译即可。
3、为什么说用protobuf比json简单高效,原因就是你用json传输数据,每次字符串里面都传输了一堆没用的数据,比如键值对的冒号,以及键值名字和值的双引号,还有大小括号,因为通讯双方都知道对应的键值名以及怎么解析json(如果不知道键值名字,收到的数据还怎么解析?)。
双方都有的数据还每次传来传去,不是浪费是什么? 纯粹就是浪费带宽和存储,要传输的对方没有的数据,这才是有用数据。有人就说,这几个括号和键值名字能浪费多少带宽和空间,别小看这些小东西,假如数据交互量大和非常频繁,你就知道了,这里面的存储空间和带宽消耗差距是可怕惊人的。
4、最后不得不佩服,google出品必属精品。
相关文章推荐
- golang gob 有什么优势? gob/protobuf/json/xml 效率对比,benchmark 压力测试
- 几种序列化协议(protobuf,xstream,jackjson,jdk,hessian)相关数据对比
- protobuf,json,xml,binary,Thrift之间的对比 .
- Protocol Buffers(protobuf)在Java开发中使用测试
- .NET平台下Redis使用(五)【StackExchange.Redis和Protobuf-net】
- Thrift,protobuf,json,xml,binary之间的对比
- 序列化协议(protobuf,xstream,jackjson,jdk,hessian)对比
- 嵌入式平台使用gtest进行白盒测试
- unity中使用protobuf(兼容ios平台)
- json, protobuf-c++,pbc,sproto 性能测试与解决方案
- protobuf,json,xml,binary,Thrift之间的对比
- 几种序列化协议(protobuf,xstream,jackjson,jdk,hessian)相关数据对比
- 几种序列化协议(protobuf,xstream,jackjson,jdk,hessian)相关数据对比
- 几种序列化协议(protobuf,xstream,jackjson,jdk,hessian)相关数据对比
- 几种序列化协议(protobuf,xstream,jackjson,jdk,hessian)相关数据对比
- 嵌入式 linux以及arm平台上网络设备测试工具iperf交叉编译以及使用
- ubuntu下使用pre-trained模型测试caffe,找不到caffe 和 protobuf的错误
- Android为啥使用org.json而不用gson, 如何更好的测试和对比这两个东西, 哪个大神能告诉我小萌头?
- unity中使用protobuf(兼容ios平台)
- c++使用Protobuf Message转Json字符串(Json库使用Json cpp)