一、为什么?
因为要做一个简单解析和生成代码,方便自己使用,不想用protobuf工具的生成cpp文件,觉得稍微麻烦一点,因为我只要简单解析和生成。不想写proto 文件。
二、工具
PC 工具
【自用工具】协议分析工具,进制转换,protobuf反序列化 - 『精品软件区』 - 吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn
web反序列化工具
Protobuf Decoder (protobuf-decoder.netlify.app)
三、原理
这种二进制协议一般都要有标志和数据长度,可以说基本属性(虽然长度可以用分割符号来区别,以前传奇就是一个特殊符号来进行数据包切割)。
protobuf 编码格式: klv 对应key length value ,其实这么看没有特别。我们自己定义协常常这样子。
key: tag << 3 | wire_type 这样子生成。 tag代表标志类似编程语言的变量名,所以在proto 里面是唯一,wire_type 写的类型。这样子就很容易对应到我们编程中的变量定义。
这个Key 不一定是一个字节,因为tag 是varint ,动态整数。这个好处方便解析进制数据,方便扩展,不用担心,插入字段导致二进制顺序,如果对一些不需要字段可以不传,这样子网络传输内存就会减少。但坏处也是扩张带来数据增加,因为key不是必须的,比喻我们网络协议所有字段都是必须,而且不会在中间插入别的字段,那么key是没有必要的,如果一个包有10字段,相当于一个包起码增加10个字节,那么我一天发送很多数据包,那么浪费一些流量。但一个很多人产品,协议是不断升级的,所以前面说的也只是绝对条件下。相对于业务开发带来的好处,这点浪费算不了什么。想想http 这种短连接,浪费多少字节,但也不照样很流行。凡事不能太极端,否则收益就很低了。
四、总结
原理我只简单写一下key 的东西,本来还想写varint ,但感觉查一下资料也比较理解。varint主要用来表示整数,主要为了省字节占用而已。tag 也是用varint表示,varint 涉及都大小端,然后还有进制操作,所以新手很难理解,我最开始不知道怎么算的,多看几次就够了。
动态解析protobuf好处,可以不用写proto文件,简单解析对应数据,然后根据经验猜出具体类型。因为wire_type 里面只是大类型,里面还有几种类型,如果没有原始proto的文件,那么只能通过自己具体业务分析具体类型。
后续补充一下自己解析c语言代码,因为当前含一些垃圾测试代码,所以暂时不贴出来。