大端儲存和小端儲存,網路位元組序

2021-06-20 18:27:28 字數 3912 閱讀 7788

一、大端、小端

"大端"和"小端"表示多位元組值的哪一端儲存在該值的起始位址處;小端儲存在起始位址處,即是小端位元組序;大端儲存在起始位址處,即是大端位元組序;

或者說:

1.小端法(little-endian)就是低位位元組排放在記憶體的低位址端(即該值的起始位址),高位位元組排放在記憶體的高位址端;

2.大端法(big-endian)就是高位位元組排放在記憶體的低位址端(即該值的起始位址),低位位元組排放在記憶體的高位址端;

舉個簡單的例子,對於整型資料0x12345678,它在大端法和小端法的系統中,各自的存放方式如下圖1所示:

二、網路位元組序

網路上傳輸的資料都是位元組流,對於乙個多位元組數值,在進行網路傳輸的時候,先傳遞哪個位元組?也就是說,當接收端收到第乙個位元組的時候,它將這個位元組作為高位位元組還是低位位元組處理,是乙個比較有意義的問題;

udp/tcp/ip協議規定:把接收到的第乙個位元組當作高位位元組看待,這就要求傳送端傳送的第乙個位元組是高位位元組;而在傳送端傳送資料時,傳送的第乙個位元組是該數值在記憶體中的起始位址處對應的那個位元組,也就是說,該數值在記憶體中的起始位址處對應的那個位元組就是要傳送的第乙個高位位元組(即:高位位元組存放在低位址處);由此可見,多位元組數值在傳送之前,在記憶體中因該是以大端法存放的;

所以說,網路位元組序是大端位元組序;

比如,我們經過網路傳送整型數值0x12345678時,在80x86平台中,它是以小端發存放的,在傳送之前需要使用系統提供的位元組序轉換函式htonl()將其轉換成大端法存放的數值;如下圖2所示:

三、位元組序測試

不同cpu平台上位元組序通常也不一樣,下面這個簡單的**可以測試不同平台上的位元組序:

#include

#include

int main(int argc,char** argv)

sparc平台上的輸出:

local order:

[0]: 0x12 addr:4290770212 //高位位元組存放在低位址處,則是大端法;

[1]: 0x34 addr:4290770213

[2]: 0x56 addr:4290770214

[3]: 0x78 addr:4290770215 //低位位元組存放在高位址處;

htonl order:

[0]: 0x12 addr:4290770212 //由此看出,主機位元組序與網路位元組一樣;

[1]: 0x34 addr:4290770213

[2]: 0x56 addr:4290770214

[3]: 0x78 addr:4290770215

x86平台上的輸出:

local order:

[0]: 0x78 addr:4289157020 //低位位元組存放在低位址處,則是小端法;

[1]: 0x56 addr:4289157021

[2]: 0x34 addr:4289157022

[3]: 0x12 addr:4289157023 //高位位元組存放在高位址處;

htonl order:

[0]: 0x12 addr:4289157020 //由此看出,主機位元組序與網路位元組不一樣;

[1]: 0x34 addr:4289157021

[2]: 0x56 addr:4289157022

[3]: 0x78 addr:4289157023

intel平台上的輸出:

local order:

[0]: 0x78 addr:1245044    //低位位元組存放在低位址處,則是小端法;

[1]: 0x56 addr:1245045

[2]: 0x34 addr:1245046

[3]: 0x12 addr:1245047    //高位位元組存放在高位址處;

htonl order:

[0]: 0x12 addr:1245044    //由此看出,主機位元組序與網路位元組不一樣;

[1]: 0x34 addr:1245045

[2]: 0x56 addr:1245046

[3]: 0x78 addr:1245047

不同的cpu有不同的位元組序型別 這些位元組序是指整數在記憶體中儲存的順序 這個叫做主機序

最常見的有兩種

le little-endian

最符合人的思維的位元組序

位址低位儲存值的低位

位址高位儲存值的高位

怎麼講是最符合人的思維的位元組序,是因為從人的第一觀感來說

低位值小,就應該放在記憶體位址小的地方,也即記憶體位址低位

反之,高位值就應該放在記憶體位址大的地方,也即記憶體位址高位

be big-endian

最直觀的位元組序

位址低位儲存值的高位

位址高位儲存值的低位

為什麼說直觀,不要考慮對應關係

只需要把記憶體位址從左到右按照由低到高的順序寫出

把值按照通常的高位到低位的順序寫出

兩者對照,乙個位元組乙個位元組的填充進去

例子:在記憶體中雙字0x01020304(dword)的儲存方式

記憶體位址

4000 4001 4002 4003

le 04 03 02 01

be 01 02 03 04

例子:如果我們將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

motorola680x()    全部    big endian

mips    nt    little endian

mips    unix    big endian

powerpc    nt    little endian

powerpc    非nt    big endian  

rs/6000    unix    big endian

sparc    unix    big endian

ixp1200 arm核心    全部    little endian

網路位元組序 大端 小端

1.小端法 little endian 就是低位位元組排放在記憶體的低位址端 即該值的起始位址 高位位元組排放在記憶體的高位址端 2.大端法 big endian 就是高位位元組排放在記憶體的低位址端 即該值的起始位址 低位位元組排放在記憶體的高位址端 網路上傳輸的資料都是位元組流,對於乙個多位元組...

大端 小端 網路位元組序

2010 10 10 17 44 58 分類 c vc c 舉報 字型大小訂閱 一 大端 小端 大端 和 小端 表示多位元組值的哪一端儲存在該值的起始位址處 小端儲存在起始位址處,即是小端位元組序 大端儲存在起始位址處,即是大端位元組序 或者說 1.小端法 little endian 就是低位位元組...

大端 小端 網路位元組序

網路位元組序 network byte order 一般是指大端 big endian,對大部分網路傳輸協議而言 傳輸,大端小端的概念是面向多位元組資料型別的儲存方式定義的,小端就是低位在前,大端就是高位在前,其中 前 是指靠近記憶體低位址,儲存在硬碟上就是先寫那個位元組 1 首先大小端是面向多位元...