大端,小端,網絡字節序總結

1、術語“小端”和“大端”

術語“小端”和“大端”表示多字節值的哪一端(小端或大端)存儲在該值的起始地址。小端存在起始地址,即是小端字節序;大端存在起始地址,即是大端字節序。

即:

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

例如:一個int型的數據佔32位,用16進製表示0x12345678

假設內存地址是 

    4000 4001 4002 4003

LE  78   56   34   12

BE  12   34   56   78

x86 系列CPU都是 小端的字節序。

如圖所示:


2、網絡字節序

網絡字節序定義:收到的第一個字節被當作高位看待,這就要求發送端發送的第一個字節應當是高位。而在發送端發送數據時,發送的第一個字節是該數字在內存中起始地址對應的字節。可見多字節數值在發送前,在內存中數值應該以大端法存放。 
網絡字節序說是大端字節序。 
比如我們經過網絡發送0x12345678
這個整形,在X86平臺中,它是以小端法存放的,在發送前需要使用系統提供的htonl將其轉換成大端法存放,如圖2所示。


爲了進行轉換 bsd socket 提供了轉換的函數 有下面四個 
htons
  unsigned short 類型從主機序轉換到網絡序 
htonl 
  unsigned long  類型從主機序轉換到網絡序 
ntohs
  unsigned short 類型從網絡序轉換到主機序 
ntohl 
  unsigned long  類型從網絡序轉換到主機序 


3、字節序測試程序 

不同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));

        i_num = htonl(i_num);
        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));

        return 0;
}


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

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章