在 Go 中解析二进制数据包(来自 C)
Parsing a binary packet (from C) in Go
我正在编写一个 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-code 来计算偏移量:
#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-program,向结构添加显式填充可能是保证 32 位和 64 位系统上相同偏移量的最佳方式。
我正在编写一个 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-code 来计算偏移量:
#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-program,向结构添加显式填充可能是保证 32 位和 64 位系统上相同偏移量的最佳方式。