c使用tcp传输的二进制数据_使用base64解决protobuf数据在http上传输的问题

有这样一种任务场景:使用protobuf序列化数据,然后通过http协议将这个序列化的数据传输给服务器。这个过程倒是比较简单,只是其中有几个问题如果不搞明白的话,很可能在应用时会遇到麻烦而耽误比较长的时间。google推出了一款grpc倒是可以非常方便地使用protobuf作为通讯接口,只是在个人使用时,总会遇到不愿意使用grpc的情况。比如已经搭建好了一个网站,如果再加个grpc的服务端就需要多启动一个服务。这时,如果数据不太敏感,直接在http协议中作为参数传递给服务端是最简单省事的一种。本文就是在这样的背景下展开。

1. 定义和编译proto文件

首先创建一个proto文件,并定一个message。然后编译生成对应的python文件。

35040449cffb48638b017861be1165fb

定义和编译proto文件

从编译产出可以看出,我们想要的python文件已经生成。

2. 存储数据并序列化

使用Person这个类型创建数据类型,并进行序列化。

5ff7e62fb4204211b64f382459800fdd

创建数据并序列化

这里需要注意了,使用protobuf序列化得到的字符串是bytes类型的。这里有必要说明一个python中两种字符序列类型:str和bytes。其中bytes是一种字节流,一般从文件中以二进制方式读取的就是这种类型。这种类型数据的优点是效率高,缺点也很明显就是可读性很差。另一个str是一种unicode类型的字符串,可以表示世界上所有的文字和标点,可读性和通用型都很不错,一般我们使用的就是这个类型。原本在网络传输中是应该使用bytes类型的,毕竟可以节省带宽。本文这种背景下的任务是通过http参数完成的,而http参数是以字符串str的形式在请求链接中存在的。因此这就需要将bytes转换成str类型,然后构造到http链接最后的参数上。

那么就有一个很直观的思路,就是直接将bytes字符串转换成str字符串,然后拼接上去,这样虽然效率很低,但是不妨一试。

13f519e3a5b0497cad74db6d42e82e03

字符串类型转化

这个时候严重的问题就出现了:将bytes字符串解码成str字符串之后内容是不一样的,而且其中还很可能包含一些http链接中不允许出现的字符。甚至连这种decode函数执行也不一定会成功。多番尝试发现,这种方式行不通,必须用其他办法。

3. 使用base64生成字符串

使用base64进行编码protobuf序列化产生的bytes字符串。

cbc1d0814b2442e2a09083dc4223c429

base64编码

发现转换之后的类型还是bytes,所以需要进行一下decode的转化。还有一个问题是这种方式加密生成的字符串还是有可能包含http链接不允许的字符,比如:+/-,空格等等。所幸base64这个工具提供了一种解决这种问题的方式。

61b3ec547e9c442b971b7eb891bec3b1

url安全的base64编码

这样得到的字符串就完全符合http参数传递的标准,然后通过 http://localhost?param=CBIVAAAqQx0AAHBCIghoZWxsby0wMQ== 就可以把字符串发送给服务器。

4. 服务器端的处理

在服务器端通过解析GET或者POST数据获取客户端传来的字符串,然后进行反序列化。

cd7e276171934b5caaab2ea105adddec

服务器端处理

可以看到解析成功,相关数据顺利传送到服务器端。到此就实现了通过http链接把protobuf数据传送到了服务器上。

本文的notebook版本文件会在GitHub上共享,感兴趣的可以在github上cnbluegeek/notebook下查看。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值