學(xué)習(xí)啦 > 學(xué)習(xí)電腦 > 網(wǎng)絡(luò)知識(shí) > 無線網(wǎng)絡(luò) > 網(wǎng)絡(luò)字節(jié)序具體知識(shí)介紹

網(wǎng)絡(luò)字節(jié)序具體知識(shí)介紹

時(shí)間: 曉斌668 分享

網(wǎng)絡(luò)字節(jié)序具體知識(shí)介紹

  最近有網(wǎng)友想了解下網(wǎng)絡(luò)字節(jié)序的知識(shí),所以學(xué)習(xí)啦小編就整理了相關(guān)資料分享給大家,具體內(nèi)容如下.希望大家參考參考!!!

  首先學(xué)習(xí)啦小編要給大家科普下什么是網(wǎng)絡(luò)字節(jié)序?

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

  轉(zhuǎn)換函數(shù)

  為了進(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.

  注意事項(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é)流,對于一個(gè)多字節(jié)數(shù)值,在進(jìn)行網(wǎng)絡(luò)傳輸?shù)臅r(shí)候,先傳遞哪個(gè)字節(jié)?也就是說,當(dāng)接收端收到第一個(gè)字節(jié)的時(shí)候,它將這個(gè)字節(jié)作為高位字節(jié)還是低位字節(jié)處理,是一個(gè)比較有意義的問題;

  UDP/TCP/IP協(xié)議規(guī)定:把接收到的第一個(gè)字節(jié)當(dāng)作高位字節(jié)看待,這就要求發(fā)送端發(fā)送的第一個(gè)字節(jié)是高位字節(jié);而在發(fā)送端發(fā)送數(shù)據(jù)時(shí),發(fā)送的第一個(gè)字節(jié)是該數(shù)值在內(nèi)存中的起始地址處對應(yīng)的那個(gè)字節(jié),也就是說,該數(shù)值在內(nèi)存中的起始地址處對應(yīng)的那個(gè)字節(jié)就是要發(fā)送的第一個(gè)高位字節(jié)(即:高位字節(jié)存放在低地址處);

  由此可見,多字節(jié)數(shù)值在發(fā)送之前,在內(nèi)存中因該是以大端法存放的; 所以說,網(wǎng)絡(luò)字節(jié)序是大端字節(jié)序; 比如,我們經(jīng)過網(wǎng)絡(luò)發(fā)送整型數(shù)值0x12345678時(shí),在80X86平臺(tái)中,它是以小端發(fā)存放的,在發(fā)送之前需要使用系統(tǒng)提供的字節(jié)序轉(zhuǎn)換函數(shù)htonl()將其轉(zhuǎn)換成大端法存放的數(shù)值;如下圖2所示:

  那么在進(jìn)行網(wǎng)絡(luò)通信時(shí)是否需要進(jìn)行字節(jié)序轉(zhuǎn)換?

  相同字節(jié)序的平臺(tái)在進(jìn)行網(wǎng)絡(luò)通信時(shí)可以不進(jìn)行字節(jié)序轉(zhuǎn)換,但是跨平臺(tái)進(jìn)行網(wǎng)絡(luò)數(shù)據(jù)通信時(shí)必須進(jìn)行字節(jié)序轉(zhuǎn)換。

  原因如下:網(wǎng)絡(luò)協(xié)議規(guī)定接收到得第一個(gè)字節(jié)是高字節(jié),存放到低地址,所以發(fā)送時(shí)會(huì)首先去低地址取數(shù)據(jù)的高字節(jié)。小端模式的多字節(jié)數(shù)據(jù)在存放時(shí),低地址存放的是低字節(jié),而被發(fā)送方網(wǎng)絡(luò)協(xié)議函數(shù)發(fā)送時(shí)會(huì)首先去低地址取數(shù)據(jù)(想要取高字節(jié),真正取得是低字節(jié)),接收方網(wǎng)絡(luò)協(xié)議函數(shù)接收時(shí)會(huì)將接收到的第一個(gè)字節(jié)存放到低地址(想要接收高字節(jié),真正接收的是低字節(jié)),所以最后雙方都正確的收發(fā)了數(shù)據(jù)。而相同平臺(tái)進(jìn)行通信時(shí),如果雙方都進(jìn)行轉(zhuǎn)換最后雖然能夠正確收發(fā)數(shù)據(jù),但是所做的轉(zhuǎn)換是沒有意義的,造成資源的浪費(fèi)。而不同平臺(tái)進(jìn)行通信時(shí)必須進(jìn)行轉(zhuǎn)換,不轉(zhuǎn)換會(huì)造成錯(cuò)誤的收發(fā)數(shù)據(jù),字節(jié)序轉(zhuǎn)換函數(shù)會(huì)根據(jù)當(dāng)前平臺(tái)的存儲(chǔ)模式做出相應(yīng)正確的轉(zhuǎn)換,如果當(dāng)前平臺(tái)是大端,則直接返回不進(jìn)行轉(zhuǎn)換,如果當(dāng)前平臺(tái)是小端,會(huì)將接收到得網(wǎng)絡(luò)字節(jié)序進(jìn)行轉(zhuǎn)換。

374603