1. 程式人生 > >大端小端 && 網路位元組序

大端小端 && 網路位元組序



(0)背景:
網路上的資料流是位元組流,對於一個多位元組數值,在進行網路傳輸的時候,先傳遞哪個位元組?也就是說,當接收端收到第一個位元組的時候,它是將這個位元組作為高位還是低位來處理呢? 


(1)網路位元組序定義:
收到的第一個位元組被當作高位看待,這就要求傳送端傳送的第一個位元組應當是高位。


(2)網路位元組序為大端序列:
在傳送端傳送資料時,傳送的第一個位元組是該數字在記憶體中起始地址對應的位元組。可見多位元組數值在傳送前,在記憶體中數值應該以大端法存放。 


htons():將16位無符號整數從本地位元組序轉換成網路位元組序;
htonl():將32位無符號整數從本地位元組序轉換成網路位元組序;
ntohs():將16位無符號整數從網路位元組序轉換成本地位元組序;
ntohl():將32位無符號整數從網路位元組序轉換成本地位元組序;


(3)舉例:
比如我們經過網路傳送0x12345678這個整形,在80X86平臺中,它是以小端法存放的,在傳送前需要使用系統提供的htonl將其轉換成大端法存放,如圖2所示。




(4)大端序列與小端序列:
1.小端法(Little-Endian)就是低位位元組排放在記憶體的低地址端即該值的起始地址,高位位元組排放在記憶體的高地址端。 
2.大端法(Big-Endian)就是高位位元組排放在記憶體的低地址端即該值的起始地址,低位位元組排放在記憶體的高地址端。


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




(5)位元組序測試函式:


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