本文承接上文,带来去protobuf的使用过程

背景:跟公司C++大佬使用protobuf协议进行通信

在跟大佬沟通过程中遇到的最大的问题是互相之间不了解数据格式等疑惑,在这里也是普及下数据的一个传输过程和字节流等内容,讲的有些零零碎碎,还请包涵

举个例子来说下一个数据格式的问题,在C++中一个整型数据可能是有符号长整型,无符号长整型。在此之外,数据还分16位和32位的区别。

我们知道,一个字节占8位,相对于二进制来说,就是多少位是几个字节

下面进入正题说下protobuf的相关问题

protobuf分为三部分,第一部分是消息内容长度(head),第二部分是消息内容类型(type),第三部分是消息体(body)

因为protobuf传入过来的是二进制的包,所以在php里面需要使用pack(),unpack()这两个函数进行解包,再将数据传到protobuf的解包函数中

举个例子说:

A向B发了一个protobuf包,A定义的这个包的第一部分(head)也就是消息体(body)的长度是4字节也就是32位的有符号长整型,第二部分(type)是2字节也就是16位的有符号短整型,然后第三部分是消息体(body)

那对于php来讲,就需要先对这个包进行解析,也就是解包

在php里面,对于加包/解包而言,就是使用pack(),unpack()这两个函数

unpack($format,$args)有两个参数,第一个参数是解包的参数,第二个参数是二进制字节流

这里参考了这个大佬的文章对二进制包进行了相关格式的解析,具体关于这两个函数的使用移步大佬
https://segmentfault.com/a/1190000008305573

按照上面的例子就是使用unpack()进行解包,

第一个4字节32位的有符号长整型对应到unpack的参数里面是I,即

unpack('Ihead',$str)

我这里在I后面定义了一个head来接受解析出来的值,在PHP里面打印出来的是一个数组

[
    'head'  => xxxx,
]

第二个2字节也就是16位的有符号短整型对应到unpack的参数里面是s,即

unpack('Ihead/stype',$str)

在这里打印出来的值是

[
    'head'  => xxxx,
    'type'  => xxxx,
]

因为我们取得是第二个2字节里面的值,所以必须把第一个4字节也带上,或者可以使用substr()把中间的2字节出去来使用unpack也行

第三部分的值使用substr取出来即可,因为前面的是6字节的head和type,所以第三部分的body就可以直接使用substr()取出即可

substr(6,str)

接下来将取出来的值放入protobuf的解析函数里面即可进行正确的读写

西班牙馅饼
7 声望0 粉丝