嵌入式设备使用protobuf进行通信
protubuf介绍
Protocol Buffers,是Google公司开发的一种数据描述语言,类似于XML能够将结构化数据序列化,可用于数据存储、通信协议等方面。
使用protobuf加密输出的数据流,因为只有发送和接收双方才知道解析的格式,所以当第三方未知proto文件内容时,数据传输是比较安全的。
项目中protubuf用途
在项目中,互联网设备需要定时推送一些数据到服务器进行存储。
然后使用的是明文传输协议,因此只要对数据部分进行protobuf加密,可以保证数据尽可能不被第三方解析到。
实战
protubuf不支持直接输出c文件,使用nanobp可以生成对应的c文件和h文件。
链接
- protobuf
https://github.com/protocolbuffers/protobuf/releases/tag/v3.19.6
旧版本会提供window可执行文件,比较方便,下载win64压缩文件。 - nanopb
https://jpa.kapsi.fi/nanopb/download/
下载nanopb-x.x.x-windows-x86.zip
一键生成
为了方便调试,我使用批命令一键生成:
.\protobuf-base\bin\protoc --python_out=. .\dev.proto
.\protobuf-base\bin\protoc dev.proto -o dev.pb
.\protobuf_nanopb\nanopb-0.4.7-windows-x86\generator-bin\nanopb_generator .\dev.pb
pause
生成dev.pb.c, dev.pb.h文件
使用pycharm模拟测试
# coding=utf-8
# file: test_proto.py
import dev_pb2
def test():
Msg = dev_pb2.Msg()
data = Msg.d.add()
data.t = 2
string = Msg.SerializeToString()
print(string)
Msg.ParseFromString(string)
print(Msg)
if __name__ == "__main__":
test()
pass
输出:
b’\n\x02\x10\x02’
d {
t: 2
}
使用nanopb生成数据
- 移植以下文件
可以看见有两个结构体定义:
/* Struct definitions */
typedef struct _pb_Msg {
pb_callback_t d;
} pb_Msg;
typedef struct _pb_Data {
uint32_t t;
} pb_Data;
将数据进行加密
pb_Msg msg = pb_Msg_init_zero;
msg.d.arg = &回调传参;
msg.d.funcs.encode = &自己定义的回调函数;
// call nanopb
pb_ostream_t ostream = pb_ostream_from_buffer(输出buf, buf大小);
pb_encode(&ostream, pb_Msg_fields , &msg)
回调函数:
DevMsg *source = (DevMsg *)(*arg);
int i;
for (i = source->countData - 1; i >= 0; i--)
{
pb_Data bodydata;
bodydata.t = source->data[i];
pb_encode_tag_for_field(ostream, field))
pb_encode_submessage(ostream, pb_Data_fields , &bodydata))
}
验证
将buf的数据以hex字符串打印,使用python进行解析
Msg.ParseFromString(bytes.fromhex("hex字符串"))
print(Msg)
结尾
旨在记录本次经历,避免后面走太多弯路~