網(wǎng)絡(luò)字節(jié)序具體知識介紹
網(wǎng)絡(luò)字節(jié)序具體知識介紹
最近有網(wǎng)友想了解下網(wǎng)絡(luò)字節(jié)序的知識,所以學(xué)習(xí)啦小編就整理了相關(guān)資料分享給大家,具體內(nèi)容如下.希望大家參考參考!!!
首先學(xué)習(xí)啦小編要給大家科普下什么是網(wǎng)絡(luò)字節(jié)序?
網(wǎng)絡(luò)字節(jié)序轉(zhuǎn)化為主機(jī)字節(jié)序時,一定要注意是否需要轉(zhuǎn)換。網(wǎng)絡(luò)字節(jié)序是確定的。網(wǎng)絡(luò)字節(jié)順序是TCP/IP中規(guī)定好的一種數(shù)據(jù)表示格式,它與具體的CPU類型、操作系統(tǒng)等無關(guān),從而可以保證數(shù)據(jù)在不同主機(jī)之間傳輸時能夠被正確解釋。網(wǎng)絡(luò)字節(jié)順序采用big endian排序方式。
轉(zhuǎn)換函數(shù)
為了進(jìn)行轉(zhuǎn)換 bsd socket提供了轉(zhuǎn)換的函數(shù) 有下面四個
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ù)會把字節(jié)序進(jìn)行轉(zhuǎn)換
在使用big endian類型的系統(tǒng)中 這些函數(shù)會定義成空宏
同樣 在網(wǎng)絡(luò)程序開發(fā)時 或是跨平臺開發(fā)時 也應(yīng)該注意保證只用一種字節(jié)序 不然兩方的解釋不一樣就會產(chǎn)生bug.
注意事項(xiàng)
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
網(wǎng)絡(luò)字節(jié)序
網(wǎng)絡(luò)上傳輸?shù)臄?shù)據(jù)都是字節(jié)流,對于一個多字節(jié)數(shù)值,在進(jìn)行網(wǎng)絡(luò)傳輸?shù)臅r候,先傳遞哪個字節(jié)?也就是說,當(dāng)接收端收到第一個字節(jié)的時候,它將這個字節(jié)作為高位字節(jié)還是低位字節(jié)處理,是一個比較有意義的問題;
UDP/TCP/IP協(xié)議規(guī)定:把接收到的第一個字節(jié)當(dāng)作高位字節(jié)看待,這就要求發(fā)送端發(fā)送的第一個字節(jié)是高位字節(jié);而在發(fā)送端發(fā)送數(shù)據(jù)時,發(fā)送的第一個字節(jié)是該數(shù)值在內(nèi)存中的起始地址處對應(yīng)的那個字節(jié),也就是說,該數(shù)值在內(nèi)存中的起始地址處對應(yīng)的那個字節(jié)就是要發(fā)送的第一個高位字節(jié)(即:高位字節(jié)存放在低地址處);
由此可見,多字節(jié)數(shù)值在發(fā)送之前,在內(nèi)存中因該是以大端法存放的; 所以說,網(wǎng)絡(luò)字節(jié)序是大端字節(jié)序; 比如,我們經(jīng)過網(wǎng)絡(luò)發(fā)送整型數(shù)值0x12345678時,在80X86平臺中,它是以小端發(fā)存放的,在發(fā)送之前需要使用系統(tǒng)提供的字節(jié)序轉(zhuǎn)換函數(shù)htonl()將其轉(zhuǎn)換成大端法存放的數(shù)值;如下圖2所示:
那么在進(jìn)行網(wǎng)絡(luò)通信時是否需要進(jìn)行字節(jié)序轉(zhuǎn)換?
相同字節(jié)序的平臺在進(jìn)行網(wǎng)絡(luò)通信時可以不進(jìn)行字節(jié)序轉(zhuǎn)換,但是跨平臺進(jìn)行網(wǎng)絡(luò)數(shù)據(jù)通信時必須進(jìn)行字節(jié)序轉(zhuǎn)換。
原因如下:網(wǎng)絡(luò)協(xié)議規(guī)定接收到得第一個字節(jié)是高字節(jié),存放到低地址,所以發(fā)送時會首先去低地址取數(shù)據(jù)的高字節(jié)。小端模式的多字節(jié)數(shù)據(jù)在存放時,低地址存放的是低字節(jié),而被發(fā)送方網(wǎng)絡(luò)協(xié)議函數(shù)發(fā)送時會首先去低地址取數(shù)據(jù)(想要取高字節(jié),真正取得是低字節(jié)),接收方網(wǎng)絡(luò)協(xié)議函數(shù)接收時會將接收到的第一個字節(jié)存放到低地址(想要接收高字節(jié),真正接收的是低字節(jié)),所以最后雙方都正確的收發(fā)了數(shù)據(jù)。而相同平臺進(jìn)行通信時,如果雙方都進(jìn)行轉(zhuǎn)換最后雖然能夠正確收發(fā)數(shù)據(jù),但是所做的轉(zhuǎn)換是沒有意義的,造成資源的浪費(fèi)。而不同平臺進(jìn)行通信時必須進(jìn)行轉(zhuǎn)換,不轉(zhuǎn)換會造成錯誤的收發(fā)數(shù)據(jù),字節(jié)序轉(zhuǎn)換函數(shù)會根據(jù)當(dāng)前平臺的存儲模式做出相應(yīng)正確的轉(zhuǎn)換,如果當(dāng)前平臺是大端,則直接返回不進(jìn)行轉(zhuǎn)換,如果當(dāng)前平臺是小端,會將接收到得網(wǎng)絡(luò)字節(jié)序進(jìn)行轉(zhuǎn)換。