在Go中解析二进制数据包来自C 使自己确信其工作方式的最佳方法可能是编写用于计算偏移量的C代码:

问题描述

我正在编写一个go应​​用程序,该应用程序通过网络侦听UDP数据包并对其进行解析。

udp数据包用C编写,其结构定义(根据其文档)如下所示。 (请理解,这是C和网络领域的新手)

typedef struct foo 
{
  int code;
  char seg[10];
  char sym[25];
  short type;
  long amtToday;
  long price;
  ...etc
} foo;

示例网络数据包如下所示

[233 3 0 0 99 100 101 95 102 111 0 0 0 0 55 52 51 57 0 69 69 68 49 48 50 48 74 65 78 50 48 50 49 0 0 58 254 127 0 0 1 0 166 58 254 127 0 0 255 255 255 255 255 255 255 255 32 232 141 0 0 0 0 0 0 135 166 58 254 127 0 0 ... etc]

简而言之,在sym字段后很难获得正确的值。

我读了一些有关C语言中结构对齐的内容,并猜测我忽略了填充值。但是我对于填充发生的位置有点困惑

是这个

typedef struct foo 
{
  int code;
  char seg[10];
  **char pad[6];**
  char sym[25];
  **char pad[7];**
  short type;
  long amtToday;
  long price;
  ...etc
} foo;

即在每个char字段之后添加填充

还是更像这样

typedef struct foo 
{
  int code;
  char seg[10];
  char sym[25];
  **char pad[1];**
  short type;
  long amtToday;
  long price;
  ...etc
} foo;

问题是我没有办法确定这两种方法是否都正确。在确认之前,我需要解析整个结构-但由于填充问题,无法解析

还是我在解析此数据包时走错了方向?

解决方法

使自己确信其工作方式的最佳方法可能是编写用于计算偏移量的C代码:

#include <stdio.h>

typedef struct foo
{
    int code;
    char seg[10];
    char sym[25];
    short type;
    long amtToday;
    long price;
} foo;

int main() {
    // What are the memory offsets between individual struct members?
    foo x;
    printf(
        "code: %ld,seg: %ld,sym: %ld,type: %ld,amtToday: %ld,price: %ld\n",(long)&x.code - (long)&x,(long)&x.seg - (long)&x,(long)&x.sym - (long)&x,(long)&x.type - (long)&x,(long)&x.amtToday - (long)&x,(long)&x.price - (long)&x
    );

    // How much space does the struct take up if we create an array for it?
    foo y[2];
    printf("offset: %ld\n",(long)&y[1] - (long)&y[0]);
    return 0;
}

输出:

code: 0,seg: 4,sym: 14,type: 40,amtToday: 48,price: 56
offset: 64

偏移量可能取决于体系结构和所使用的编译器。如果您能够编辑C程序,则在结构中添加显式填充可能是保证在32位和64位系统上具有相同偏移量的最佳方法。