关于htonl和ntohl。这两行代码中的任何一行何时评估为false。
htonl(x) == ntohl(x);
htonl(ntohl(x)) == htonl(htonl(x));
换句话说,这两个操作何时不等同于在同一台机器上?我能想到的唯一场景是一台机器,它不能用于表示整数的2的补码。
原因主要是历史,编码清晰度还是其他原因?
现在是否存在任何现代架构或环境,在这些架构或环境中,在同一台机器上进行网络字节顺序转换是不同方向的相同代码?
答案 0 :(得分:6)
我找不到Posix规范的原始草稿,但最近的一个found online有一个提示。
网络字节顺序可能不便于处理实际值。 为此,将值存储为普通值更为明智 整数。这称为“主机字节顺序”。在主机字节顺序中:
The most significant bit might not be stored in the first byte in address order. **Bits might not be allocated to bytes in any obvious order at all.**
存储在uint8_t对象中的8位值不会 需要转换为主机字节顺序或从主机字节顺序转换,因为它们具有相同 表示。可以使用。转换16位和32位值 htonl(),htons(),ntohl()和ntohs()函数。
有趣的是,以下陈述是在
的讨论下作出的POSIX标准明确要求8位字符和二进制补码算法。
这基本上排除了我对1的补码机器实现的想法。
但是“任何明显的命令”声明基本上都表明posix委员会至少认为运行posix / unix运行于大或小端以外的东西的可能性。因此,不能排除声明htonl和ntohl作为不同的实现。
所以简短的回答是“htonl和ntohl是相同的实现,但是两个不同函数的接口是为了将来与未知的兼容。”
答案 1 :(得分:5)
多年前我为UNIVAC 1100系列大型机写了一个TCP / IP堆栈。这是一个36位,可字寻址的计算机体系结构,具有1的补码算法。
当这台机器进行通信I / O时,来自外部世界的8位字节将被放入每个9位四分之一字的低8位。所以在这个系统上,ntohl()会将每个四分之一字中的8位压缩到字的低32位(前4位为零),因此你可以对它进行算术运算。
同样,htonl()将取一个字中的低32位并撤消此操作,将每个8位数量放入每个9位四分之一字的低8位。
因此,为了回答原始问题,这台计算机体系结构上的ntohl()和htonl()操作彼此非常不同。
例如:
COMP* . COMPRESS A WORD
LSSL A0,36 . CLEAR OUT A0
LSSL A1,1 . THROW AWAY TOP BIT
LDSL A0,8 . GET 8 GOOD ONE'S
LSSL A1,1 .
LDSL A0,8 .
LSSL A1,1 .
LDSL A0,8 .
LSSL A1,1 .
LDSL A0,8 .
J 0,X9 .
.
DCOMP* . DECOMPRESS A WORD
LSSL A0,36 . CLEAR A0
LSSL A1,4 . THROW OUT NOISE
LDSL A0,8 . MOVE 8 GOOD BITS
LSSL A0,1 . ADD 1 NOISE BIT
LDSL A0,8 . MOVE 8 GOOD BITS
LSSL A0,1 . ADD 1 NOISE BIT
LDSL A0,8 . MOVE 8 GOOD BITS
LSSL A0,1 . ADD 1 NOISE BIT
LDSL A0,8 . MOVE 8 GOOD BITS
J 0,X9 .
COMP相当于ntohl()和DCOMP到htonl()。对于那些不熟悉UNIVAC 1100汇编代码的人:-) LSSL是“Left Single Shift Logical”的一个寄存器,由多个位置组成。 LDSL是指定计数的“左双移逻辑”对的一对寄存器。因此,LDSL A0,8将连接的A0,A1寄存器移位8位,将A1的高8位移入A0的低8位。
此代码是1981年为UNIVAC 1108编写的。几年后,当我们有一个1100/90并且它开发了一个C编译器时,我开始了一个BSD NET / 2 TCP / IP实现的端口并实现了ntohl( )和htonl()以类似的方式。可悲的是,我从未完成那项工作..
如果你想知道为什么某些互联网RFC使用术语“八位字节”,因为当天的某些计算机(如PDP-10,Univacs等)的“字节”不是8位。 “八位字节”专门定义为8位字节。
答案 2 :(得分:-2)
并非所有机器都具有相同的字节顺序,这些方法会处理这些问题。假设'网络秩序'是大端。如果您的计算机运行大端架构并运行ntohl,则输出将与输入相同(因为字节序与网络相同)。如果您的机器是一个小端架构,ntohl会将数据从大端转换为小端。关于htonl也是如此(必要时将主机数据转换为网络字节顺序)。要回答您的问题,当您在具有不同字节顺序的两台计算机之间传输数据时,这两项操作并不等效。