【问题标题】:Wrong port endianness in TCP/UDP headerTCP/UDP 标头中的端口字节序错误
【发布时间】:2021-03-20 01:07:47
【问题描述】:

我们知道Endianness 有两种类型 - 大端 (BE) 和小端 (LE)。所以通常我们在应用层有 LE,即所谓的“主机字节顺序”。
通常在应用程序中,我们将传输协议的主机字节顺序(LE)端口转换为网络字节顺序(BE)这样的方式:

struct sockaddr_in sockaddr = {0};
// ...
sockaddr.sin_port = htons(60592);

几乎所有网络协议都使用 BE 字节表示。

在此示例中,主机字节顺序中的60592 将是ECB0,正如我的计算器所说的那样。所以我认为它应该在传输头内部交换到B0EC,但事实并非如此。我哪里错了?

【问题讨论】:

  • 我相信你有它倒退。存储在 LE 中的数字 60592 实际上是 0xB0EC。
  • “我们知道有两种类型的字节序 - 大字节序 (BE) 和小字节序 (LE)”。我多么希望那是真的。幸运的是,除非你想支持 40 多年前的硬件,否则你可以假装它是。

标签: c networking tcp udp endianness


【解决方案1】:

60592 是十六进制的 0xECB0。作为一个 16 位无符号值,分为两个 8 位字节,最低有效字节的值为 0xB0,最高有效字节的值为 0xEC。使用 little endian 字节顺序的机器将首先将值存储在内存最低有效字节中,因此它将存储为序列 0xB0, 0xEC。如果使用memcpy() 将这两个字节复制到网络数据包中,则这些字节将以相同的顺序出现在数据包中 0xB0, 0xEC。但是网络协议以大端字节序表示 16 位值,因此字节序列 0xB0、0xEC 表示 16 位无符号值 0xB0EC 或 45292。

在使用 little endian 字节顺序的机器上,htons(60592) 将产生值 45292 或 0xB0EC。这将作为字节序列 0xEC、0xB0 存储在内存中。当使用memcpy() 复制到网络数据包中时,字节将以相同的顺序出现在数据包中 0xEC, 0xB0。在使用大端字节序的网络协议中,字节序列0xEC,0xB0代表16位,无符号值0xECB0或60592根据需要。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-23
    • 1970-01-01
    • 2013-12-03
    • 2016-02-18
    • 2013-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多