htons中的混淆-小端/大端

9
当我通过套接字从一个进程发送整数变量到另一个进程,并在接收端打印该值时,即使没有使用ntohl / htonl,该值仍然保持不变,那么我需要在哪里使用这些函数,除了初始化套接字结构之外?我了解大小端。但是为什么我们需要将端口和IP号转换为主机/网络字节顺序,当值保持不变时。请详细说明如何在网络上传输整数?
3个回答

17
如果您希望程序具有可移植性,那么每当您通过网络发送一个大小超过1个字节的整数时,您必须先使用htonshtonl将其转换为网络字节序,接收计算机必须使用ntohsntohl将其转换为主机字节序。
在您的情况下,数值仍然相同的原因可能是发送计算机和接收计算机的字节序相同。换句话说,您正在使用的发送计算机和接收计算机都是小端(或大端)字节序。
但如果要使程序具有可移植性,则不能依赖于这种情况始终如此。例如,有一天,发送计算机可能是Intel x86,接收计算机可能是Sun SPARC,如果不使用htons,则您的程序将失败。

我编写了客户端和服务器,没有使用 htonl 和 ntohl。假设我发送了数字 6,服务器接收到的也是数字 6。那么这些函数有什么必要性呢? - avd
5
这些函数的需求在于,当客户端在小端字节序计算机上运行,而服务器在大端字节序计算机上运行,或者反之亦然时。 - Charles Salvia
非整数数据类型如结构体呢?它们有字节序吗? - Andrew McKinlay
@AndrewMcKinlay 结构体成员按照定义的顺序进行排序。但是还有其他问题,比如填充: https://dev59.com/4nE85IYBdhLWcg3wgDlI#2749096 - Prashanth Chandra
我不同意整个第一段。串行化和反串行化是可以在没有 hton*ntoh* 的情况下实现的,而且事实上这些函数并不能保证执行串行化。 - autistic

9
如果你想将数据从x86或amd64机器发送到一个带有PowerPC处理器的机器,以二进制格式传输时,你会很快发现你的数据会遇到“NUXI问题”,因为不同的处理器对整数的处理方式不同,似乎交换了字节。(实际上它们并没有交换字节--它们只是按照不同的顺序处理字节。)
在x86或amd64上工作时,最低有效字节在内存中排在第一位(这样你可以从较低的内存地址开始执行加法运算)。PowerPC将最高有效字节放在内存的第一位(这样你可以根据先出现在内存中的字节对数字进行排序--字符串排序和整数排序可以完全相同)。

0

它保持不变,因为在您的架构上,网络顺序与本机顺序相同。如果您从未预计将代码编译为另一种架构,则可以省略hton / ntoh调用。然后,您的代码将无法移植。


1
这不正确。他可能正在使用主机顺序与网络顺序不同的架构。只有当两个端点的架构具有相同的字节顺序时,您的代码才能在没有 htonX/ntohX 的情况下“工作”。 - R Samuel Klatchko
你说得对 -- 我本意是想表达那个意思,但我的回答不够清晰。 - Jim Garrison

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接