http://www.cnblogs.com/mailingfeng/archive/2012/09/27/2705502.html
字節順序是指佔內存多於一個字節類型的數據在內存中的存放順序,通常有小端、大端兩種字節順序。小端字節序指低字節數據存放在內存低地址處,高字節數據存放在內存高地址處;大端字節序是高字節數據存放在低地址處,低字節數據存放在高地址處。
網絡字節順序採用 big endian (大端)排序方式 , 即將低位字節排在前。
不同的
CPU 有不同的字節序類型
這些字節序是指整數在內存中保存的順序 這個叫做主機序
最常見的有兩種
1
.
Little endian :將低序字節存儲在起始地址
2
.
Big endian :將高序字節存儲在起始地址
note:
java中對int轉byte, 永遠是去低8位的字節, 不用去管系統內部字節順序. 當你傳向網絡時,
你就要自己進行網絡字節順序發, 先發低位字節,再發高位字節.
LE little-endian
最符合人的思維的字節序
地址低位存儲值的低位
地址高位存儲值的高位
怎麼講是最符合人的思維的字節序,是因爲從人的第一觀感來說
低位值小,就應該放在內存地址小的地方,也即內存地址低位
反之,高位值就應該放在內存地址大的地方,也即內存地址高位
BE big-endian
最直觀的字節序
地址低位存儲值的高位
地址高位存儲值的低位
爲什麼說直觀,不要考慮對應關係
只需要把內存地址從左到右按照由低到高的順序寫出
把值按照通常的高位到低位的順序寫出
兩者對照,一個字節一個字節的填充進去
例子:如果我們將
0x1234abcd 寫入到以
0x0000 開始的內存中,則結果爲
big-endian little-endian
0x0000 0x12 0xcd
0x0001 0x23 0xab
0x0002 0xab 0x34
0x0003 0xcd 0x12
x86
系列
CPU 都是
little-endian 的字節序
.
網絡字節順序是
TCP/IP 中規定好的一種數據表示格式,它與具體的
CPU 類型、操作系統等無關,從而可以保證數據在不同主機之間傳輸時能夠被正確解釋。網絡字節順序採用
big endian 排序方式。 (一般的操作系統,在往網絡上發送字節流的時候,已經進行了相應的"轉網絡序"處理, 從網絡上接受字節流則相反)
爲了進行轉換
bsd socket 提供了轉換的函數
有下面四個
htons
把
unsigned short 類型從主機序轉換到網絡序
htonl
把
unsigned long 類型從主機序轉換到網絡序
ntohs
把
unsigned short 類型從網絡序轉換到主機序
ntohl
把
unsigned long 類型從網絡序轉換到主機序
在使用
little endian 的系統中這些函數會把字節序進行轉換(與網絡序不一致)
在使用
big endian 類型的系統中
這些函數會定義成空宏(與網絡序一致,無需額外轉換)
同樣
在網絡程序開發時 或是跨平臺開發時
也應該注意保證只用一種字節序 不然兩方的解釋不一樣就會產生
bug.
(即需要注意不同主機序下系統之間的網絡數據交流, 在發送(或接受)那一刻保持一致的字節序)
注:
1
、網絡與主機字節轉換函數
:htons ntohs htonl ntohl (s
就是 short l 是
long h 是
host n 是
network)
2 、不同的 CPU
上運行不同的操作系統,字節序也是不同的,參見下表。
處理器
操作系統
字節排序
Alpha
全部
Little endian
HP-PA NT Little endian
HP-PA UNIX Big endian
Intelx86 全部
Little endian <-----x86 系統是小端字節序系統
Motorola680x()
全部
Big endian
MIPS NT Little endian
MIPS UNIX Big endian
PowerPC NT Little endian
PowerPC 非 NT Big endian <-----PPC
系統是大端字節序系統
RS/6000 UNIX Big endian
SPARC UNIX Big endian
IXP1200 ARM 核心
全部
Little endian