c - 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
,但事实并非如此。我哪里错了?
解决方案
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根据需要。
推荐阅读
- android - 使用意图打开所有电子商务应用程序
- ios - height 和 maxY,width 和 maxW 有什么区别?
- javascript - res.download 功能在 express.js 中不起作用
- elasticsearch - 解析 log4net 日志并转发到 Logstash
- command - 同时发送两条命令 telegram-cli
- javascript - 如何在node js中同步读取文本文件并将行组合在一起
- javascript - 在 JavaScript 中递归计算整数数组的总和
- c# - 需要帮助在 C# 中计算 MD5 哈希
- java - java.sql.SQLException:“pos”参数不能 < 1
- wordpress - 通过 Wordpress Rest API 更新帖子时仅出现 403 错误