網路位元組順序與主機位元組順序轉換

2021-10-19 20:56:10 字數 4422 閱讀 9924

網路位元組順序與主機位元組順序轉換

在進行網路程式設計時,由於網路位元組的順序和主機的位元組順序可能存在不同,需要進行轉換以統一「格式」

網路位元組順序是tcp/ip中規定好的一種資料表示格式,它與具體的cpu型別、作業系統等無關,從而可以保證資料在不同主機之間傳輸時能夠被正確解釋。網路位元組順序採用big endian排序方式,統一格式可以避免相容性問題。

不同的機器的主機位元組順序(hbo)不一定相同,與cpu設計有關。

詳解

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

最常見的有兩種

1. little-endian:將低序位元組儲存在起始位址

2. big-endian :將高序位元組儲存在起始位址

le(little-endian)將位址低位儲存值的低位,將位址高位儲存值的高位,是最符合人的思維的位元組序。因為從人的思維來說低位值小,就應該放在記憶體位址小的地方,也即記憶體位址低位;反之,高位值大就應該放在記憶體位址大的地方,也即記憶體位址高位。

be(big-endian)的位址低位儲存的是值的高位,位址高位儲存的是值的低位,它是最直觀的位元組序。說直觀是它不需要考慮對應關係,只需要把記憶體位址從左到右按照由低到高的順序寫出;把值按照通常的高位到低位的順序寫出,兩者對照,乙個位元組乙個位元組的填充進去。例如:

在記憶體中雙字0x01020304的儲存方式

記憶體位址

4000 4001 4002 4003

le 04 03 02 01

be 01 02 03 04

如果我們將0x1234abcd寫入到以0x0000開始的記憶體中,則結果為

記憶體位址be le

0x0000 0x12 0xcd

0x0001 0x23 0xab

0x0002 0xab 0x34

0x0003 0xcd 0x12

通常來說,x86 cpu是little-endian。而一般arm cpu也是little-endian。

但是當前常見的開發板使用的處理器比如s3c2410a、s3c2440等都是大小端支援的,可以通過軟體選擇。

網路中傳輸的資料有的和本地位元組儲存順序一致,而有的則截然不同,為了資料的一致性,就要把本地的資料轉換成網路上使用的格式,然後傳送出去,接收的時候也是一樣的,經過轉換然後才去使用這些資料,基本的庫函式中提供了這樣的可以進行位元組轉換的函式,如和htons( ) htonl( ) ntohs( ) ntohl( ),這裡n表示network,h表示host,htons( ) htonl( )用於本地位元組向網路位元組轉換的場合,s表示short,即對2位元組操作,l表示long即對4位元組操作。同樣ntohs( )ntohl( )用於網路位元組向本地格式轉換的場合

1、htons 把unsigned short型別從主機序轉換到網路序

2、htonl 把unsigned long型別從主機序轉換到網路序

3、ntohs 把unsigned short型別從網路序轉換到主機序

4、ntohl 把unsigned long型別從網路序轉換到主機序

在使用little endian的系統中 這些函式會把位元組序進行轉換,在使用big endian型別的系統中這些函式會定義成空巨集。

其他型別位元組序轉換

long long 型別的網路位元組順序轉換

可以通過位移的方式實現

位元組序就是位元組的順序,就是大於乙個位元組型別的資料在記憶體中的存放順序(乙個位元組的資料當然就無需談順序的問題了)。

其實大部分人在實際的開發中都很少會直接和位元組序打交道。唯有在跨平台以及網路程式中位元組序才是乙個應該被考慮的問題。

位元組序分為兩類:big-endian和little-endian。引用標準的big-endian和little-endian的定義如下:

a) little-endian就是低位位元組排放在記憶體的低位址端,高位位元組排放在記憶體的高位址端。

b) big-endian就是高位位元組排放在記憶體的低位址端,低位位元組排放在記憶體的高位址端。

c) 網路位元組序:4個位元組的32 bit值以下面的次序傳輸:首先是0~7bit,其次8~15bit,然後16~23bit,最後是24~31bit。這種傳輸次序稱作大端位元組序。由於 tcp/ip首部中所有的二進位制整數在網路中傳輸時都要求以這種次序,因此它又稱作網路位元組序。比如,乙太網頭部中2位元組的「乙太網幀型別」,表示後面資料的型別。對於arp請求或應答的乙太網幀型別來說,在網路傳輸時,傳送的順序是0x08,0x06。在記憶體中的映象如下所示:

棧頂 (低位址)

該字段的值為0x0806。按照大端方式存放在記憶體中。

首先我們要知道我們c程式映像中記憶體的空間布局情況:在《c專家程式設計》中或者《unix環境高階程式設計》中有關於記憶體空間布局情況的說明,大致如下圖:

----------------------- 最高記憶體位址 0xffffffff

| 棧底

.. 棧.棧頂

||/|/null (空洞)

/|/|

堆未初始化的資料

----------------(統稱資料段)

初始化的資料

正文段(**段)

----------------------- 最低記憶體位址 0x00000000

以上圖為例如果我們在棧上分配乙個unsigned char buf[4],那麼這個陣列變數在棧上是如何布局的呢?看下圖:

棧底 (高位址)

buf[3]

buf[2]

buf[1]

buf[0]

棧頂 (低位址)

現在我們弄清了高低位址,接著來弄清高/低位元組,如果我們有乙個32位無符號整型0x12345678(恰好是把上面的那4個位元組buf看成乙個整型),那麼高位是什麼,低位又是什麼呢?其實很簡單。在十進位制中我們都說靠左邊的是高位,靠右邊的是低位,在其他進製也是如此。就拿 0x12345678來說,從高位到低位的位元組依次是0x12、0x34、0x56和0x78。

高低位址和高低位元組都弄清了。我們再來回顧一下big-endian和little-endian的定義,並用圖示說明兩種位元組序:以unsigned int value = 0x12345678為例,分別看看在兩種位元組序下其儲存情況,我們可以用unsigned char buf[4]來表示value:

big-endian: 低位址存放高位,如下圖:

棧底 (高位址)

buf[3] (0x78) – 低位

buf[2] (0x56)

buf[1] (0x34)

buf[0] (0x12) – 高位

棧頂 (低位址)

棧底 (高位址)

buf[3] (0x12) – 高位

buf[2] (0x34)

buf[1] (0x56)

buf[0] (0x78) – 低位

棧頂 (低位址)

嵌入式系統開發者應該對little-endian和big-endian模式非常了解。採用little-endian模式的cpu對運算元的存放方式是從低位元組到高位元組,而big-endian模式對運算元的存放方式是從高位元組到低位元組。

例如,16bit寬的數0x1234在little-endian模式cpu記憶體中的存放方式(假設從位址0x4000開始存放)為:

記憶體位址 存放內容

0x4001 0x12

0x4000 0x34

而在big-endian模式cpu記憶體中的存放方式則為:

記憶體位址 存放內容

0x4001 0x34

0x4000 0x12

32bit寬的數0x12345678在little-endian模式cpu記憶體中的存放方式(假設從位址0x4000開始存放)為:

記憶體位址 存放內容

0x4003 0x12

0x4002 0x34

0x4001 0x56

0x4000 0x78

而在big-endian模式cpu記憶體中的存放方式則為:

記憶體位址 存放內容

0x4003 0x78

0x4002 0x56

0x4001 0x34

0x4000 0x12

部分情況參見下表。

處理器 作業系統 位元組排序

alpha 全部 little endian

hp-pa nt little endian

hp-pa unix big endian

intelx86 全部 little endian <-----x86系統是小端位元組序系統

motorola680x() 全部 big endian

mips nt little endian

mips unix big endian

powerpc nt little endian

powerpc 非nt big endian <-----ppc系統是大端位元組序系統

rs/6000 unix big endian

sparc unix big endian

ixp1200 arm核心 全部 little endian

主機位元組順序和網路位元組順序

不同的cpu有不同的位元組序型別 這些位元組序是指整數在記憶體中儲存的順序 這個叫做主機序 最常見的有兩種 1 little endian 將低序位元組儲存在起始位址 2 big endian 將高序位元組儲存在起始位址 le little endian 最符合人的思維的位元組序 位址低位儲存值的低...

位元組順序 網路位元組順序

位元組順序 位元組順序是指佔記憶體多於乙個位元組型別的資料在記憶體中的存放順序,通常有小端 大端 兩種位元組順序。小端位元組序 指低位元組資料存放在記憶體低位址處,高位元組資料存放在記憶體高位址處 大端 位元組序是高位元組資料存放在低位址處,低位元組資料存放在高位址處。記憶體位址增長是從低位址到高位...

網路位元組順序

本文摘自 不同的cpu有不同的位元組序型別 這些位元組序是指整數在記憶體中儲存的順序 這個叫做主機序 最常見的有兩種1 little endian2 big endian le little endian 最符合人的思維的位元組序 位址低位儲存值的低位 位址高位儲存值的高位 怎麼講是最符合人的思維的...