首页 > 解决方案 > TCP/UDP 标头中的端口字节序错误

问题描述

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

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

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

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

在此处输入图像描述

标签: cnetworkingtcpudpendianness

解决方案


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根据需要。


推荐阅读