大端法、小端法、網絡字節序

《UNXI網絡編程》定義:術語“小端”和“大端”表示多字節值的哪一端(小端或大端)存儲在該值的起始地址。小端存在起始地址,即是小端字節序;大端存在起始地址,即是大端字節序。

也可以說:
1.小端法(Little-Endian)就是低位字節排放在內存的低地址端即該值的起始地址,高位字節排放在內存的高地址端。
2.大端法(Big-Endian)就是高位字節排放在內存的低地址端即該值的起始地址,低位字節排放在內存的高地址端。

舉個簡單的例子,對於整形0x12345678。它在大端法和小端法的系統內中,分別如圖1所示的方式存放。

zijiexu_pic_1  

網絡字節序

我們知道網絡上的數據流是字節流,對於一個多字節數值,在進行網絡傳輸的時候,先傳遞哪個字節?也就是說,當接收端收到第一個字節的時候,它是將這個字節作爲高位還是低位來處理呢?
網絡字節序定義:收到的第一個字節被當作高位看待,這就要求發送端發送的第一個字節應當是高位。而在發送端發送數據時,發送的第一個字節是該數字在內存中起始地址對應的字節。可見多字節數值在發送前,在內存中數值應該以大端法存放。
網絡字節序說是大端字節序。
比如我們經過網絡發送0x12345678這個整形,在80X86平臺中,它是以小端法存放的,在發送前需要使用系統提供的htonl將其轉換成大端法存放
,如圖2所示。

zijiexu_pic_2

字節序測試程序

不同cpu平臺上字節序通常也不一樣,下面寫個簡單的C程序,它可以測試不同平臺上的字節序。

#include   < stdio . h >
#include   < netinet / in . h >
int   main()
{
    int   i_num   =   0x12345678 ;
    printf ( " [0]:0x%x/n " ,   * (( char   * ) & i_num   +   0 ));
    printf ( " [1]:0x%x/n " ,   * (( char   * ) & i_num   +   1 ));
    printf ( " [2]:0x%x/n " ,   * (( char   * ) & i_num   +   2 ));
    printf ( " [3]:0x%x/n " ,   * (( char   * ) & i_num   +   3 ));
10   
11      i_num   =   htonl(i_num);
12      printf ( " [0]:0x%x/n " ,   * (( char   * ) & i_num   +   0 ));
13      printf ( " [1]:0x%x/n " ,   * (( char   * ) & i_num   +   1 ));
14      printf ( " [2]:0x%x/n " ,   * (( char   * ) & i_num   +   2 ));
15      printf ( " [3]:0x%x/n " ,   * (( char   * ) & i_num   +   3 ));
16   
17      return   0 ;
18  }  


在80X86CPU平臺上,執行該程序得到如下結果:
[0]:0x78
[1]:0x56
[2]:0x34
[3]:0x12

[0]:0x12
[1]:0x34
[2]:0x56
[3]:0x78

分析結果,在80X86平臺上,系統將多字節中的低位存儲在變量起始地址,使用小端法。htonl將i_num轉換成網絡字節序,可見網絡字節序是大端法。

總結點:80X86使用小端法,網絡字節序使用大端法。

 

轉自:http://www.cnblogs.com/motadou/archive/2009/01/18/1564714.html

發佈了109 篇原創文章 · 獲贊 5 · 訪問量 64萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章