6

我刚刚开始使用 C++ 进行一些原始网络编程,并且一直在我的 Raspberry Pi 上进行编译(没有交叉编译)。这使得一切都是小端的。

构建 IP 标头后,我计算了 IP 校验和,但结果总是不正确(基于此处的示例http://www.thegeekstuff.com/2012/05/ip-header-checksum/)。

加快 gdb,我已经解决了 IP 标头中前 32 位的排序问题。该示例使用0x4500003C,表示版本 4 ( 0x4)、IHL 5 ( 0x5)、TOS 0 ( 0x00) 和 tot_length 60 ( 0x003C)。所以我将我的数据包设置为相同。

struct iphdr* ip; // Also some mallocing
ip->version = 4;
ip->ihl = 5;
ip->tos = 0;
ip->tot_len = 60;

现在在 gdb 中,我检查了前 32 位,0x3C000045因为字节序而期待,但我得到了这个:

(gdb) print ip
$1 = (iphdr *) 0x11018
(gdb) x/1xw 0x11018
0x11018:        0x003c0045

前 16 位是小端(0x0045),但第二个,包含十进制 60,似乎是大端(0x003C)!

这是什么给的?我疯了吗?我对结构内的字节顺序完全错误吗?(绝对有可能)

4

2 回答 2

7

结构中有字段的顺序,然后是多字节字段中的字节顺序。

0x003C根本不是字节序,它是 60 的十六进制值。当然,它以某种字节序存储在内存中,但是你用来写字段的顺序和你用来读回它的顺序是一样的——两者都是Raspberry Pi 的本机字节顺序,它们相互抵消。

通常你会想写:

ip->tot_len = htons(60);

将 16 位字段存储到数据包中时。还有htonl32 位字段,以及ntohsntohl网络数据包中读取字段。

于 2012-10-01T23:41:48.377 回答
1

ARM 架构可以同时运行小端和大端,但 Android 平台运行的是小端。

于 2012-10-11T18:35:25.553 回答