pcap中的ntohs()究竟做了什么?

时间:2013-04-08 09:08:27

标签: pcap endianness

我从其中一个答案中读到了文档:

ntohs函数采用TCP / IP网络字节顺序的16位数字(AF_INET或AF_INET6地址族),并以主机字节顺序返回一个16位数字。

请解释一个例子,如什么是网络字节顺序以及主机字节顺序是什么。

1 个答案:

答案 0 :(得分:30)

数字1000是二进制,1111101000。

如果是16位二进制数,那就是0000001111101000。

如果将其分成两个8位字节,则为两个字节,值为00000011和11101000。

这两个字节可以有两个不同的顺序:

  • 在“big-endian”字节顺序中,包含高8位的字节为第一位,低8位的字节为第二位,因此第一个字节为00000011,第二个字节为11101000。
  • 在“little-endian”字节顺序中,包含 lower 8位的字节是第一个,包含 upper 8位的字节是第二个,所以第一个byte是11101000,第二个字节是00000011。

在字节可寻址机器中,硬件可以是“big-endian”或“little-endian”,具体取决于哪个字节存储在内存中较低的地址。大多数个人电脑都是小端的;大型计算机有big-endian和little-endian两种类型,大型计算机(例如IBM大型机和中型计算机以及SPARC服务器)都是大端计算机。

大多数网络都是位串行的,因此这些位是一个接一个地传输的。可以首先使用最高有效位或最低有效位来传输字节的位,但是网络硬件将从处理器隐藏这些细节。但是,它们将按照它们在主机内存中的顺序传输 bytes ,因此,如果一个小端机器正在向big-endian机器传输数据,那么little-endian的数量机器传输在接收大端机上会有所不同;这些差异被网络硬件隐藏。

因此,为了允许big-endian和little-endian机器在每个协议层进行通信,要么:

  • 需要选择“标准”字节顺序,并且使用不同字节顺序的机器需要移动多字节数字的字节,以便在传输数据之前它们不在机器的标准字节顺序中,移动它们,以便在收到数据后,它们 在机器的标准字节顺序中;
  • 两台机器需要协商会话的特定字节顺序(例如,对于X11网络窗口协议,从客户端到服务器的初始消息指定要使用的字节顺序);
  • 协议消息需要指定正在使用的字节顺序(例如,使用DCE RPC完成;这是用于“Microsoft RPC”的协议);
  • 接收机器需要以某种方式正确猜测字节顺序(我不知道任何当前使用的协议已经完成,但旧的BSD“talk”协议没有使用上面使用的任何技术,并且Sun386i的实现必须使用它来处理大端摩托罗拉68K机器和小端英特尔x86机器。

各种Internet协议使用第一种策略,将big-endian指定为字节顺序;它在各种RFC中被称为“网络字节顺序”。 (Microsoft的SMB文件访问协议也使用第一种策略,但指定了little-endian。)

所以“网络字节顺序”是大端的。 “主机字节顺序”是您正在使用的机器的字节顺序;它可能是big-endian,在这种情况下ntohs()只返回你给它的值,或者它可能是little-endian,在这种情况下ntohs()交换你给它的值的两个字节和返回该值。例如,在大端机器上,ntohs(1000)将返回1000,并且在小端机器上,ntohs(1000)将交换高位和低位字节,给出1110100000000011二进制或小数为59395。