socket编程中将数据包大小拆分为字节传输

发布时间 2023-06-28 10:39:49作者: Boom__Clap

两端自定义网络协议时,需要对传输的数据包格式进行约定,比如TLV格式,约定数据包头部固定几个字节传的是包头,包头的内容也需要约定。

这里讲一种表示数据包大小的方式,

比如首先约定包最大长度只能为60KB,也就是uint16即可表示,

为什么?

因为60KB = 60 * 1024B = 61440B,数据包都是字节数组,所以数据包的最大长度是61440个字节,uint16的最大值是65535,大于数据包的最大长度,用uint16即可表示,uint16是16位二进制数,2个字节。

 

我们采用位运算,将数据包的大小值,拆分为两个字节进行存储,一个高字节,一个低字节,

header := make([]byte, 2)
header[0] = byte((dataSize >> 8) & 0xff) 
header[1] = byte(dataSize & 0xff)   

在这段代码中,使用 (dataSz >> 8) & 0xff 将数据包大小的高字节提取出来。

原因是,数据包大小的高字节存储在整数的第二个字节(从右往左数第二个字节)。通过将数据包大小右移 8 位,将第二个字节移动到最低有效位的位置。然后,使用按位与操作符 & 和位掩码 0xff 提取字节。

在这里,右移 8 位(即 dataSz >> 8)是基于数据包大小占用了两个字节(约定数据包长度最大值为60 * 1024 = 61440)。通过右移 8 位,我们将第二个字节移动到最低有效位的位置,以便提取。

可以将这个过程与将整数拆分为多个字节的过程进行类比。在那个过程中,我们使用右移操作符和按位与操作符将整数的各个字节提取出来。而在这个特定的代码段中,我们只需要提取第二个字节,因此使用右移 8 位即可。

综上所述,为了提取数据包大小的高字节,我们使用 (dataSz >> 8) & 0xff 中的右移 8 位操作。这样可以将第二个字节移动到最低有效位的位置,并使用按位与操作符提取字节。