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

tab*_*ces 12 endianness pcap

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

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

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

小智 31

数字1000是二进制的,1111101000.

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

如果它被分成两个8位字节,那就是两个字节,值为00000011和11101000.

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

  • 在"big-endian"字节顺序中,包含高8位的字节是第一个,而低8位的字节是第二个,因此第一个字节是00000011,第二个字节是11101000.
  • 在"小端"字节顺序中,包含 8位的字节是第一个,包含 8位的字节是第二个,因此第一个字节是11101000,第二个字节是00000011.

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

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

因此,为了允许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()交换你给它的值的两个字节并返回该值.例如,在big-endian机器上,ntohs(1000)将返回1000,并且在小端机器上,ntohs(1000)将交换高位和低位字节,给出1110100000000011二进制或59395十进制.