【问题标题】:Problems with endianess on Raspberry PiRaspberry Pi 上的字节序问题
【发布时间】:2012-10-01 23:31:47
【问题描述】:

我刚刚开始使用 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)!

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

【问题讨论】:

  • 与你的问题完全无关 - 怎么样 - 想买一个 ;-)
  • 去做吧! 3000 美分中的每一分都值得

标签: c++ endianness


【解决方案1】:

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

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

通常你会想写:

ip->tot_len = htons(60);

将 16 位字段存储到数据包中时。还有 htonl 用于 32 位字段,ntohsntohl 用于从网络数据包中读取字段。

【讨论】:

  • 啊,我的故障排除太深入了,直接通过了明显的答案。我曾尝试使用 htons 以 16 位的形式读回我的标题,但它们仍然不正常。在存储时使用它作用于单个字段而不是 16 位段,正确存储内容。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2018-01-08
    • 1970-01-01
    • 2012-09-14
    • 1970-01-01
    • 2022-01-17
    • 1970-01-01
    • 2017-06-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多