📜  Unix套接字-网络字节顺序

📅  最后修改于: 2020-11-05 04:52:10             🧑  作者: Mango


不幸的是,并非所有计算机都以相同的顺序存储包含多字节值的字节。考虑一个由2个字节组成的16位Internet。有两种存储此值的方法。

  • 小尾数-在此方案中,低位字节存储在起始地址(A)上,高位字节存储在下一个地址(A +1)上。

  • 大尾数-在此方案中,高位字节存储在起始地址(A)上,低位字节存储在下一个地址(A + 1)上。

为了允许具有不同字节顺序约定的机器相互通信,Internet协议为通过网络传输的数据指定了规范的字节顺序约定。这称为网络字节顺序。

建立Internet套接字连接时,必须确保sockaddr_in结构的sin_port和sin_addr成员中的数据以网络字节顺序表示。

字节排序功能

在主机的内部表示和网络字节顺序之间转换数据的例程如下-

Function Description
htons() Host to Network Short
htonl() Host to Network Long
ntohl() Network to Host Long
ntohs() Network to Host Short

下面列出的是有关这些功能的更多详细信息-

  • unsigned short htons(unsigned short hostshort) -此函数将16位(2字节)数量从主机字节顺序转换为网络字节顺序。

  • unsigned long htonl(unsigned long hostlong) -此函数将32位(4字节)数量从主机字节顺序转换为网络字节顺序。

  • unsigned short ntohs(unsigned short netshort) -此函数将16位(2字节)数量从网络字节顺序转换为主机字节顺序。

  • 无符号长ntohl(无符号长netlong) -此函数将32位数量从网络字节顺序转换为主机字节顺序。

这些函数是宏,导致将转换源代码插入到调用程序中。在小端机器上,代码会将值更改为网络字节顺序。在big-endian机器上,由于不需要插入任何代码,因此不会插入任何代码。这些函数定义为null。

确定主机字节顺序的程序

将以下代码保存在byteorder.c文件中,然后对其进行编译并在您的计算机上运行它。

在此示例中,我们将两个字节的值0x0102存储在短整数中,然后查看两个连续的字节c [0](地址A)和c [1](地址A+ 1)来确定字节顺序。

#include 

int main(int argc, char **argv) {

   union {
      short s;
      char c[sizeof(short)];
   }un;
    
   un.s = 0x0102;
   
   if (sizeof(short) == 2) {
      if (un.c[0] == 1 && un.c[1] == 2)
         printf("big-endian\n");
      
      else if (un.c[0] == 2 && un.c[1] == 1)
         printf("little-endian\n");
      
      else
         printf("unknown\n");
   }
   else {
      printf("sizeof(short) = %d\n", sizeof(short));
   }
    
   exit(0);
}

该程序在奔腾机器上生成的输出如下-

$> gcc byteorder.c
$> ./a.out
little-endian
$>