理解這幾個概念前,首先要遵循計算機以及通信中的幾個規(guī)則:
1. 一個數(shù)字轉(zhuǎn)化為16進(jìn)制后,最左邊的字節(jié)是最高字節(jié),最右邊的字節(jié)為最低字節(jié)。
2. 計算機中內(nèi)存的最小單位是字節(jié),也就是8個bit。讀寫數(shù)據(jù)時,先使用低地址,再用高地址內(nèi)存。
3. 數(shù)據(jù)傳輸過程中,也是按1個字節(jié)1個字節(jié)傳輸?shù)?,發(fā)送時,先發(fā)送低地址的內(nèi)存;接收時,把先接收到的數(shù)據(jù)存放在較低內(nèi)存中。
1.主機字節(jié)序
比如現(xiàn)在有一個數(shù)a,值為857870592,轉(zhuǎn)化成16進(jìn)制為0x33221100,根據(jù)規(guī)則1:其中00是最低字節(jié),33是最高字節(jié)。a一共占了4個字節(jié),剛好需要4個字節(jié)的內(nèi)存。
現(xiàn)在有一塊內(nèi)存,其中地址100是低地址內(nèi)存,地址103是高地址內(nèi)存:
| 地址 | 數(shù)據(jù) |
|---|---|
| 103(高地址) | 空 |
| 102 | 空 |
| 101 | 空 |
| 100(低地址) | 空 |
當(dāng)要把數(shù)據(jù)a存入這塊內(nèi)存中時時,根據(jù)規(guī)則2,低地址100會先被填充,但是并沒有規(guī)定是先填充a的最高字節(jié)33還是a的最低字節(jié)00。此時就有了大端格式和小端格式兩種存法:
- 大端格式:數(shù)據(jù)的高字節(jié)(33)保存在內(nèi)存的低地址(100)中,而數(shù)據(jù)的低字節(jié)(00)保存在內(nèi)存的高地址(103)。
-
小端格式:數(shù)據(jù)的低字節(jié)(00)保存在內(nèi)存的低地址(100)中,而數(shù)據(jù)的高字節(jié)(33)保存在內(nèi)存的高地址(103)。
所以,如果按大端格式,有如下布局:
| 地址 | 數(shù)據(jù) |
|---|---|
| 103(高地址) | 0x00 |
| 102 | 0x11 |
| 101 | 0x22 |
| 100(低地址) | 0x33 |
如果按小端格式,有如下布局:
| 地址 | 數(shù)據(jù) |
|---|---|
| 103(高地址) | 0x33 |
| 102 | 0x22 |
| 101 | 0x11 |
| 100(低地址) | 0x00 |
可以這樣方便記憶,大端格式是先取出數(shù)據(jù)的最高字節(jié)進(jìn)行處理,小端格式是先取出數(shù)據(jù)的最低位處理。
2.網(wǎng)絡(luò)字節(jié)序
解決了主機內(nèi)存的數(shù)據(jù)存儲方式,現(xiàn)在來解決網(wǎng)絡(luò)通信過程中的數(shù)據(jù)傳輸順序問題,UDP/TCP/IP協(xié)議規(guī)定:把接收到的第一個字節(jié)當(dāng)作高位字節(jié)看待,這就要求發(fā)送端發(fā)送的第一個字節(jié)是高位字節(jié),相當(dāng)于先處理高位的字節(jié)。根據(jù)規(guī)則3,先發(fā)送內(nèi)存低字節(jié)的數(shù)據(jù),所以內(nèi)存低字節(jié)的數(shù)據(jù)保存的是高位字節(jié),即大端格式。所以UDP/TCP/IP是一種大端格式,發(fā)送主機和接收主機都要是大端格式的才能正確的通信,如果收發(fā)主機格式不同,就需要用相關(guān)的函數(shù)先轉(zhuǎn)化下。
3.Intel和Motorola數(shù)據(jù)格式
從事嵌入式軟件開發(fā)的人可能聽說過這兩種格式,比如在CAN協(xié)議中,一幀報文可以發(fā)送8個字節(jié),在應(yīng)用層軟件中,可以用以下結(jié)構(gòu)體表示一幀報文:
typedef struct CANMSG{
u32 STDID;
u32 EXDID;
u16 DL;
u8 data[8];
}CANMSG;
現(xiàn)在我想將數(shù)據(jù)0x1100通過CAN協(xié)議發(fā)出去,在填充data數(shù)組時,是按什么順序呢?
如果按照Intel格式,data[0] = 0x00,data[1]=0x11
如果按照Motorola格式,data[0]=0x11,data[1]=0x00
當(dāng)然還有其他復(fù)雜的情況,這里就不詳細(xì)說了。