網絡字節序和主機字節序

關於字節序(大端法、小端法)的定義

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

 

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

舉個簡單的例子,對於整形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]:0x12spa

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

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

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

轉自:http://www.blogjava.net/tinysun/archive/2009/12/31/307952.html內存

相關文章
相關標籤/搜索