Unix套接字 - 網路位元組序



不幸的是,並非所有計算機都以相同的順序儲存構成多位元組值的位元組。考慮一個由2個位元組組成的16位整數。有兩種方法可以儲存此值。

  • 小端序 - 在此方案中,低位位元組儲存在起始地址 (A) 上,高位位元組儲存在下一個地址 (A + 1) 上。

  • 大端序 - 在此方案中,高位位元組儲存在起始地址 (A) 上,低位位元組儲存在下一個地址 (A + 1) 上。

為了允許具有不同位元組順序約定的機器相互通訊,網際網路協議指定了透過網路傳輸資料的規範字節順序約定。這稱為網路位元組序。

在建立網際網路套接字連線時,必須確保sockaddr_in結構中的sin_port和sin_addr成員中的資料以網路位元組序表示。

位元組排序函式

在主機內部表示和網路位元組序之間轉換資料的例程如下:

函式 描述
htons() 主機到網路短整型
htonl() 主機到網路長整型
ntohl() 網路到主機長整型
ntohs() 網路到主機短整型

下面是關於這些函式的更多細節:

  • unsigned short htons(unsigned short hostshort) - 此函式將16位(2位元組)數量從主機位元組序轉換為網路位元組序。

  • unsigned long htonl(unsigned long hostlong) - 此函式將32位(4位元組)數量從主機位元組序轉換為網路位元組序。

  • unsigned short ntohs(unsigned short netshort) - 此函式將16位(2位元組)數量從網路位元組序轉換為主機位元組序。

  • unsigned long ntohl(unsigned long netlong) - 此函式將32位數量從網路位元組序轉換為主機位元組序。

這些函式是宏,會導致將轉換原始碼插入到呼叫程式中。在小端序機器上,程式碼會將值更改為網路位元組序。在大端序機器上,不會插入任何程式碼,因為不需要任何程式碼;這些函式被定義為空。

確定主機位元組序的程式

將以下程式碼儲存在名為byteorder.c的檔案中,然後編譯並執行它。

在此示例中,我們將兩位元組值 0x0102 儲存在短整型中,然後檢視兩個連續的位元組 c[0](地址 A)和 c[1](地址 A + 1)以確定位元組序。

#include <stdio.h>

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
$>
廣告