将结构转换为Go中的字节切片的紧凑方法是什么?

时间:2016-02-18 03:06:56

标签: networking go struct casting padding

在编写网络代码时,我们经常发现自己从字节切片填充结构以访问对象形式的数据。

让我们来看看这个结构

type PACKETHEAD struct {
    Type uint16
    Size uint16
    Hash uint32
}

以及以某种方式填充数据的字节切片

data := make([]byte, 1024)

我的解决方案是

var pkthead PACKETHEAD
pktsiz := unsafe.Sizeof(pkthead)
pktbuf := bytes.NewReader(buf[:pktsiz])
err = binary.Read(pktbuf, binary.BigEndian, &pkthead)
if err != nil {
    // handle it
}

但是

  • 它使用unsafe

  • 每次演员需要~7行代码(如果我们有数百个不同的数据包会怎么样)

  • 无法轻易打包到Cast(*struct, data)函数

  • 无法控制struct padding,如果go的编译器决定在网络一端的成员之间添加额外的字节?

  • binary.Read执行数据副本如果我没有弄错(这不一定是骗局)

在C中,在两个网络端都只有#pragma pack(1),同意一种类型的endianess

最后PACKETHEAD* pkt = (PACKETHEAD*)dataptr;

我们如何用Go实现同样的目标?

祝你有愉快的一天, 克里斯

1 个答案:

答案 0 :(得分:3)

gopack的无耻插件,I(和其他人)编写的库用来支持Go中的bitpacking。注意:如果这是一个问题,它会使用不安全的操作。