Socket 網路位元組順序


不幸的是,所有的計算機的位元組儲存在相同的順序組成的多位元組值。請考慮,是由2個位元組的一個16位元的基於整數。有兩種方法來儲存這個值。

  • Little Endian: 在這個方案中,低位位元組儲存在起始地址(A)和高位位元組儲存的下一個地址(A + 1).

  • Big Endian: 在這個方案中的高位位元組的開始地址(A),並儲存在低位位元組的下一個地址上儲存(A+1).

因此,不同位元組順序的慣例,機器可以進行通訊,網際網路協定指定一個規範的位元組順序公約“在網路上傳輸的資料。這被稱為網路位元組順序。

建立因特網通訊端連線時,必須確保域sin_port和sin_addr成員sockaddr_in結構中的資料在網路位元組順序表示。

位元組排序功能:

主機的內部表示,網路位元組順序之間轉換資料的例程:

函式 描述
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位元組)為單位批次轉換為主機位元組順序。

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

這些功能是在轉換的原始碼插入到呼叫程式中的巨集和結果。在little-endian的機器程式碼將改變周圍的值轉換為網路位元組順序。在大端機器沒有插入程式碼,因為沒有需要的功能定義為空(null).

程式來確定主機位元組順序:

請將下面的程式碼在一個檔案byteorder.c和,然後在機器上編譯並執行它。

在這個例子中,我們兩個位元組值0x0102儲存在短整型,然後看看在連續兩個位元組,c[0](地址)和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
$>