日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

大端模式小端模式 主机序网络序

發(fā)布時(shí)間:2024/4/20 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 大端模式小端模式 主机序网络序 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1.?主機(jī)序

不同的CPU有不同的字節(jié)序類型這些字節(jié)序是指整數(shù)在內(nèi)存中保存的順序,這個(gè)叫做主機(jī)序。最常見的有兩種:

1.?????????Little endian將低序字節(jié)存儲(chǔ)在起始地址。?小端模式

2.?????????Big endian將高序字節(jié)存儲(chǔ)在起始地址。????大端模式

LE little-endian

最符合人的思維的字節(jié)序。地址低位存儲(chǔ)值的低位,地址高位存儲(chǔ)值的高位。怎么講是最符合人的思維的字節(jié)序,是因?yàn)閺娜说牡谝挥^感來說低位值小,就應(yīng)該放在內(nèi)存地址小的地方,也即內(nèi)存地址低位;反之,高位值就應(yīng)該放在內(nèi)存地址大的地方,也即內(nèi)存地址高位。

BE big-endian

最直觀的字節(jié)序。地址低位存儲(chǔ)值的高位,地址高位存儲(chǔ)值的低位。為什么說直觀,不要考慮對(duì)應(yīng)關(guān)系。只需要把內(nèi)存地址從左到右按照由低到高的順序?qū)懗?/span>,把值按照通常的高位到低位的順序?qū)懗?#xff0c;兩者對(duì)照,一個(gè)字節(jié)一個(gè)字節(jié)的填充進(jìn)去。

例子:在內(nèi)存中雙字0x01020304(DWORD)的存儲(chǔ)方式:

內(nèi)存地址

4000 4001 4002 4003

LE ??04 ??03 ??02 ??01

BE ??01 ??02 ??03 ??04

?

例子:1.如果我們將0x1234abcd寫入到以0x0000開始的內(nèi)存中,則結(jié)果為:

big-endian??little-endian

0x0000??0x12?????0xcd

0x0001??0x23??????0xab

0x0002??0xab????? 0x34

0x0003??0xcd??????0x12

x86系列CPU都是little-endian的字節(jié)序。

二、網(wǎng)絡(luò)序

網(wǎng)絡(luò)字節(jié)順序TCP/IP中規(guī)定好的一種數(shù)據(jù)表示格式,它與具體的CPU類型、操作系統(tǒng)等無關(guān),從而可以保證數(shù)據(jù)在不同主機(jī)之間傳輸時(shí)能夠被正確解釋。網(wǎng)絡(luò)字節(jié)順序采用big endian排序方式

為了進(jìn)行轉(zhuǎn)換?bsd socket提供了轉(zhuǎn)換的函數(shù)有下面四個(gè):

1.?????htons?unsigned short類型從主機(jī)序轉(zhuǎn)換到網(wǎng)絡(luò)序。

2.?????htonl?unsigned long類型從主機(jī)序轉(zhuǎn)換到網(wǎng)絡(luò)序。

3.?????ntohs?unsigned short類型從網(wǎng)絡(luò)序轉(zhuǎn)換到主機(jī)序。

4.?????ntohl?unsigned long類型從網(wǎng)絡(luò)序轉(zhuǎn)換到主機(jī)序。

在使用little endian的系統(tǒng)中這些函數(shù)會(huì)把字節(jié)序進(jìn)行轉(zhuǎn)換,在使用big endian類型的系統(tǒng)中這些函數(shù)會(huì)定義成空宏。同樣在網(wǎng)絡(luò)程序開發(fā)時(shí)或是跨平臺(tái)開發(fā)時(shí),也應(yīng)該注意保證只用一種字節(jié)序,不然兩方的解釋不一樣就會(huì)產(chǎn)生bug。

1.?????網(wǎng)絡(luò)與主機(jī)字節(jié)轉(zhuǎn)換函數(shù):htons ntohs htonl ntohl?(s就是shortllonghhostnnetwork)

2.?????不同的CPU上運(yùn)行不同的操作系統(tǒng),字節(jié)序也是不同的,參見下表

處理器????操作系統(tǒng)????字節(jié)排序

Alpha????全部????Little endian

HP-PA????NT????Little endian

HP-PA????UNIX????Big endian

Intelx86????全部????Little endian <-----x86系統(tǒng)是小端字節(jié)序系統(tǒng)

Motorola680x()????全部????Big endian
MIPS????NT????Little endian
MIPS????UNIX????Big endian
PowerPC????NT????Little endian
PowerPC????
NT????Big endian??<-----PPC系統(tǒng)是大端字節(jié)序系統(tǒng)

RS/6000????UNIX????Big endian
SPARC????UNIX????Big endian
IXP1200 ARM
核心????全部????Little endian

三、一些注意點(diǎn)

1.BIG-ENDIAN、LITTLE-ENDIAN跟多字節(jié)類型的數(shù)據(jù)有關(guān)的比如int,short,long型,而對(duì)單字節(jié)數(shù)據(jù)byte卻沒有影響。BIG-ENDIAN就是低位字節(jié)排放在內(nèi)存的高端,高位字節(jié)排放在內(nèi)存的低端。而LITTLE-ENDIAN正好相反。

  比如 int a = 0x05060708

  在BIG-ENDIAN的情況下存放為:

  字節(jié)號(hào) 0 1 2 3

  數(shù)據(jù) 05 06 07 08

  在LITTLE-ENDIAN的情況下存放為:

  字節(jié)號(hào) 0 1 2 3

  數(shù)據(jù) 08 07 06 05

  2.BIG-ENDIAN、LITTLE-ENDIAN、跟CPU有關(guān)的,每一種CPU不是BIG-ENDIAN就是LITTLE- ENDIAN、。IA架構(gòu)的CPU中是Little-Endian,而PowerPC 、SPARC和Motorola處理器。這其實(shí)就是所謂的主機(jī)字節(jié)序。而網(wǎng)絡(luò)字節(jié)序是指數(shù)據(jù)在網(wǎng)絡(luò)上傳輸時(shí)是大頭還是小頭的,在Internet的網(wǎng)絡(luò)字節(jié)序是BIG-ENDIAN。所謂的JAVA字節(jié)序指的是在JAVA虛擬機(jī)中多字節(jié)類型數(shù)據(jù)的存放順序,JAVA字節(jié)序也是BIG-ENDIAN。

  3.所以在用C/C++寫通信程序時(shí),在發(fā)送數(shù)據(jù)前務(wù)必用htonl和htons去把整型和短整型的數(shù)據(jù)進(jìn)行從主機(jī)字節(jié)序到網(wǎng)絡(luò)字節(jié)序的轉(zhuǎn)換,而接收數(shù)據(jù)后對(duì)于整型和短整型數(shù)據(jù)則必須調(diào)用ntohl和ntohs實(shí)現(xiàn)從網(wǎng)絡(luò)字節(jié)序到主機(jī)字節(jié)序的轉(zhuǎn)換。如果通信的一方是JAVA程序、一方是 C/C++程序時(shí),則需要在C/C++一側(cè)使用以上幾個(gè)方法進(jìn)行字節(jié)序的轉(zhuǎn)換,而JAVA一側(cè),則不需要做任何處理,因?yàn)镴AVA字節(jié)序與網(wǎng)絡(luò)字節(jié)序都是 BIG-ENDIAN,只要C/C++一側(cè)能正確進(jìn)行轉(zhuǎn)換即可(發(fā)送前從主機(jī)序到網(wǎng)絡(luò)序,接收時(shí)反變換)。如果通信的雙方都是JAVA,則根本不用考慮字節(jié)序的問題了。

  4.如果網(wǎng)絡(luò)上全部是PowerPC,SPARC和Motorola CPU的主機(jī)那么不會(huì)出現(xiàn)任何問題,但由于實(shí)際存在大量的IA架構(gòu)的CPU,所以經(jīng)常出現(xiàn)數(shù)據(jù)傳輸錯(cuò)誤。

  5.如果程序運(yùn)行在X86架構(gòu)的PC SERVER上,發(fā)送數(shù)據(jù)的一端用C實(shí)現(xiàn)的,接收一端是用JAVA實(shí)現(xiàn)的,而發(fā)送端在發(fā)送數(shù)據(jù)前未進(jìn)行從主機(jī)字節(jié)序到網(wǎng)絡(luò)字節(jié)序的轉(zhuǎn)換,這樣接收端接收到的是LITTLE-ENDIAN的數(shù)據(jù),數(shù)據(jù)解釋自然出錯(cuò)。

  

四、引用他人的

http://blog.csdn.net/xuyanbo2008/article/details/7458007

一、大端模式&小端模式

所謂的“大端模式”,是指數(shù)據(jù)的低位(就是權(quán)值較小的后面那幾位)保存在內(nèi)存的高地址中,而數(shù)據(jù)的高位,保存在內(nèi)存的低地址中,這樣的存儲(chǔ)模式有點(diǎn)兒類似于把數(shù)據(jù)當(dāng)作字符串順序處理:地址由小向大增加,而數(shù)據(jù)從高位往低位放;

所謂的“小端模式”,是指數(shù)據(jù)的低位保存在內(nèi)存的低地址中,而數(shù)據(jù)的高位保存在內(nèi)存的高地址中,這種存儲(chǔ)模式將地址的高低和數(shù)據(jù)位權(quán)有效地結(jié)合起來,高地址部分權(quán)值高,低地址部分權(quán)值低,和我們的邏輯方法一致。

如果將一個(gè)32位的整數(shù)0x12345678 存放到一個(gè)整型變量(int)中,這個(gè)整型變量采用大端或者小端模式在內(nèi)存中的存儲(chǔ)由下表所示。為簡(jiǎn)單起見,本文使用OP0表示一個(gè)32位數(shù)據(jù)的最高字節(jié)MSB(Most Significant Byte),使用OP3表示一個(gè)32位數(shù)據(jù)最低字節(jié)LSB(Least Significant Byte)。??

地址偏移??????? 大端模式?????? 小端模式?
0x00?????????? 12(OP0)????? 78(OP3)?
0x01?????????? 34(OP1)????? 56(OP2)?
0x02?????????? 56(OP2)????? 34(OP1)?
0x03?????????? 78(OP3)????? 12(OP0)


小端:較高的有效字節(jié)存放在較高的存儲(chǔ)器地址,較低的有效字節(jié)存放在較低的存儲(chǔ)器地址。
大端:較高的有效字節(jié)存放在較低的存儲(chǔ)器地址,較低的有效字節(jié)存放在較高的存儲(chǔ)器地址。

采用大小模式對(duì)數(shù)據(jù)進(jìn)行存放的主要區(qū)別在于在存放的字節(jié)順序大端方式將高位存放在低地址,小端方式將高位存放在高地址。采用大端方式進(jìn)行數(shù)據(jù)存放符合人類的正常思維,而采用小端方式進(jìn)行數(shù)據(jù)存放利于計(jì)算機(jī)處理。到目前為止,采用大端或者小端進(jìn)行數(shù)據(jù)存放,其孰優(yōu)孰劣也沒有定論。

下面這段代碼可以用來測(cè)試一下你的編譯器是大端模式還是小端模式:

short int x;
char x0,x1;
x=0x1122;
x0=((char*)&x)[0]; //低地址單元
x1=((char*)&x)[1]; //高地址單元
若x0=0x11,則是大端; 若x0=0x22,則是小端......
上面的程序還可以看出,數(shù)據(jù)尋址時(shí),用的是低位字節(jié)的地址

二、主機(jī)序&網(wǎng)絡(luò)序

不同的 CPU 有不同的字節(jié)序類型這些字節(jié)序是指整數(shù)在內(nèi)存中保存的順序這個(gè)叫做主機(jī)序,最常見的有兩種:?
1、Little endian :將低序字節(jié)存儲(chǔ)在起始地址?
2、Big endian :將高序字節(jié)存儲(chǔ)在起始地址

網(wǎng)絡(luò)字節(jié)順序是TCP/IP中規(guī)定好的一種數(shù)據(jù)表示格式,它與具體的CPU類型、操作系統(tǒng)等無關(guān),從而可以保證數(shù)據(jù)在不同主機(jī)之間傳輸時(shí)能夠被正確解釋。網(wǎng)絡(luò)字節(jié)順序采用big endian排序方式。

為了進(jìn)行轉(zhuǎn)換 bsd socket提供了轉(zhuǎn)換的函數(shù) 有下面四個(gè):
htons 把unsigned short類型從主機(jī)序轉(zhuǎn)換到網(wǎng)絡(luò)序
htonl 把unsigned long類型從主機(jī)序轉(zhuǎn)換到網(wǎng)絡(luò)序
ntohs 把unsigned short類型從網(wǎng)絡(luò)序轉(zhuǎn)換到主機(jī)序
ntohl 把unsigned long類型從網(wǎng)絡(luò)序轉(zhuǎn)換到主機(jī)序


在使用little endian的系統(tǒng)中,這些函數(shù)會(huì)把字節(jié)序進(jìn)行轉(zhuǎn)換?
在使用big endian類型的系統(tǒng)中,這些函數(shù)會(huì)定義成空宏

同樣,在網(wǎng)絡(luò)程序開發(fā)時(shí),或是跨平臺(tái)開發(fā)時(shí),也應(yīng)該注意保證只用一種字節(jié)序,不然兩方的解釋不一樣就會(huì)產(chǎn)生BUG。

注:
1、網(wǎng)絡(luò)與主機(jī)字節(jié)轉(zhuǎn)換函數(shù):htons ntohs htonl ntohl (s 就是short l是long h是host n是network)
2、不同的CPU上運(yùn)行不同的操作系統(tǒng),字節(jié)序也是不同的,參見下表:


處理器???????????? 操作系統(tǒng)???? 字節(jié)排序
Alpha?????????????????? 全部????? Little endian
HP-PA??????????????????? NT?????? Little endian
HP-PA?????????????????? UNIX???? Big endian
Intelx86??????????????? 全部???? Little endian <-----x86系統(tǒng)是小端字節(jié)序系統(tǒng)
Motorola680x()????????? 全部??? Big endian
MIPS???????????????????? NT?????? Little endian
MIPS??????????????????? UNIX??? Big endian
PowerPC????????????????? NT???? Little endian
PowerPC???????????????? 非NT??? Big endian?? <-----PPC系統(tǒng)是大端字節(jié)序系統(tǒng)
RS/6000???????????????? UNIX??? Big endian
SPARC?????????????????? UNIX??? Big endian
IXP1200 ARM核心???????? 全部????? Little endian

下面是一個(gè)檢驗(yàn)本機(jī)字節(jié)序的簡(jiǎn)便方法:

//判斷本機(jī)的字節(jié)序
//返回true表為小段序。返回false表示為大段序
bool am_little_endian ()
{
unsigned short i=1;
return (int)*((char *)(&i)) ? true : false;
}
int main()
{
?? if(am_little_endian())
{
???????? ?? printf("本機(jī)字節(jié)序?yàn)樾《涡?\n");
}
else
{
????????? printf("本機(jī)字節(jié)序?yàn)榇蠖涡?\n");
}
??????? return 0;
}

三、入棧地址高低問題

堆棧是在內(nèi)存中指定的一段特殊存儲(chǔ)區(qū),存起始單元的地址叫棧底,當(dāng)前存儲(chǔ)單元地址叫棧頂,堆棧存儲(chǔ)區(qū)一旦指定,棧底就固定不變了,而棧頂是隨入棧、出棧操作呈動(dòng)態(tài)。而不同機(jī)型的堆棧設(shè)計(jì),有兩種情況:一是每入棧一個(gè)數(shù),棧頂?shù)刂芳?,每出棧一個(gè)數(shù),棧頂?shù)刂窚p1,即堆棧區(qū)是由內(nèi)存的低地址向高地址。另一種是每入棧一個(gè)數(shù),棧頂?shù)刂窚p1,每出棧一個(gè)數(shù),棧頂?shù)刂芳?,即堆棧區(qū)是由內(nèi)存的高地址向低地址。高地址、低地址是相對(duì)而言,即相對(duì)地址編碼的大小而言。

總結(jié)

以上是生活随笔為你收集整理的大端模式小端模式 主机序网络序的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。