duanpai1033 2016-02-18 03:06
浏览 70


When writing network code we often find ourselves populating structs from byte slices to access the data in form of an object.

Let's take this struct

type PACKETHEAD struct {
    Type uint16
    Size uint16
    Hash uint32

and a byte slice that has been somehow populated with data

data := make([]byte, 1024)

My solution would be to

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


  • It uses unsafe

  • Requires ~7 lines of code for every cast (what if we had hundreds of different packets)

  • Can't be trivially packed into a Cast(*struct, data) function

  • No control over struct padding, what If go's compiler decides to add extra bytes in between members on one end of a network?

  • binary.Read performs a data copy if I'm not mistaken (this isn't necessarily a con)

In C one would just #pragma pack(1) on both network ends, agree on one type of endianess

and finally PACKETHEAD* pkt = (PACKETHEAD*)dataptr;

How can we achieve the same thing with Go?

Have a nice day, Kris

  • 写回答

1条回答 默认 最新

  • duandou8120 2016-02-18 05:36

    Shameless plug for gopack, a library I (and others) wrote to support bitpacking in Go. Note: it uses unsafe operations under the hood, if that's a problem.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?



  • ¥15 win10,这种情况怎么办
  • ¥15 如何在配置使用Prettier的VSCode中通过Better Align插件来对齐等式?(相关搜索:格式化)
  • ¥100 在连接内网VPN时,如何同时保持互联网连接
  • ¥15 MATLAB中使用parfor,矩阵Removal的有效索引在parfor循环中受限制
  • ¥20 Win 10 LTSC 1809版本如何无损提升到20H1版本
  • ¥50 win10 LTSC 虚拟键盘不弹出
  • ¥30 微信小程序请求失败,网页能正常带锁访问
  • ¥30 德飞莱51单片机实现C4炸弹
  • ¥50 CrossLink-LIF-MD6000 型 FPGA 的 CMOS 转 MIPI D-PHY IP 核功能使用异常
  • ¥15 proteus控制16x16LED点阵显示屏的设计