網路傳輸中遇到的位元組序問題

2021-06-27 21:30:41 字數 2269 閱讀 7296

因為本人最近做的專案是路由器和交換機管理平台的開發,所以經常會遇到在一台路由器上測試沒有任何問題,但是在另一台裝置上測試就出現了問題的現象,最後發現還是位元組序的問題,雖然對位元組序的問題每次都很重視,但是總是在開發中遺漏或者忽略,位元組序問題真是令人防不勝防。究其根本原因,一方面是因為自己對位元組序的理解還停留在表面上,另一方面可能還是開發經驗不足吧,呵呵。

在網上看到了許多講位元組序的文章,大部分都講到了位元組序的基本含義,大家一看也都明白位元組序是怎麼回事,但是在具體開發過程中還是總想不到或者時刻注意著卻還是一不小心就出現了問題,可能還是理解的不夠透徹,下面我就講一下我自己的理解,基本的定義還是參考字節序的定義,裡面加了一些自己的理解,我覺得這樣好理解一些,希望我的講解能讓大家對位元組序有更深的理解一些或者是更容易理解吧,高手勿噴,多多包涵,有不當的地方請指出,大家共同進步。

首先還是老生常談介紹一下位元組序的含義:

位元組序又

稱端序,端序最早是從格列佛遊記中提到的,小人國的內戰就源於吃雞蛋時是從大端(big-endian)開始吃還是從小端(little-endian)開始吃,大端就是雞蛋的圓頭,小端就是雞蛋的尖頭。用在資料裡面也就是高位資料是大大端,低位資料是小端,如0x1234,12是高位元組資料,所以就是大端,34是低位元組資料,所以就是小端。

通過上面的講解,大家應該對大端和小端有了了解,那麼在商業領域也有一些cpu廠家,有些廠家覺得訪問資料應該從大端開始,比如powerpc、motorola,有些廠家就覺得應該從小端開始,比如intel、amd。那麼從大端開始訪問資料和從小端開始訪問資料有什麼不一樣呢,下面就給大家介紹一下:

稍微對位元組序有些了解的同學都知道大端位元組序和小端位元組序的基本區別,這裡順便提一下:

大端位元組序(big-endian):高位址記憶體單元存低位元組資料,低位址記憶體單元存高位元組資料

小端位元組序

(little-endian):高位址記憶體單元存高位元組資料,低位址記憶體單元存低位元組資料

兩者正好相反,那麼是怎麼造成這種情況的呢,先給大家說乙個基本知識,大家在申請記憶體空間的時候,不管是棧記憶體還是堆記憶體,申請記憶體以後記憶體的首位址都指向這段記憶體的最低位元組單元,對這段記憶體進行操作也是使用記憶體的首位址進行操作的。

現在首先說明大端環境下資料的訪問情況,假如現在有乙個32位整數0x12345678,現在將它存進乙個4位元組記憶體中,記憶體首位址為ptr,因為上面說過了大端位元組序上訪問資料都是從高位元組資料開始的,所以,這裡先把12開始存到ptr指向的記憶體單元0,接著取34,將34存到ptr+1的記憶體單元中,依次存完,這樣就把0x12345678存到了這乙個4位元組記憶體中了,低位元組資料存在4位元組記憶體的高記憶體位址單元,高位元組資料存在4位元組記憶體的低記憶體位址單元。

在小端環境下資料的訪問情況,依舊是將32位整數0x12345678存進乙個4位元組記憶體中,記憶體首位址是ptr(上面已經講過,記憶體首位址都是在低位址的,任何編譯器都是這樣做的),因為上面已經說過小端位元組序上訪問資料是從低位元組資料開始的,所以這裡就先把78存到ptr指向的記憶體單元0,接著取56,將56存到ptr+1的記憶體單元中,依次存完,這樣就把0x12345678存到了這乙個4位元組記憶體中了,低位元組資料存在4位元組記憶體的低記憶體位址單元,高位元組資料存在4位元組記憶體的高記憶體位址單元。

但是其實訪問資料不像上面講的乙個位元組乙個位元組的訪問的,其實在cpu上有資料匯流排和控制匯流排,在32位cpu上,乙個時鐘週期就把這32位資料訪問完了。大家可以想象32根資料匯流排和記憶體相連(大端和小端上不差別),分配資料匯流排都是先把資料給第一根匯流排,第一根匯流排總是和低位址的低位位元相連,在大端裝置上資料是從高位元組資料開始的,所以就先把高位元組資料的8位給了1-7的這八根資料線,剩下的依次分配,最後在乙個時鐘週期內把這32位資料存到了記憶體裡,這樣造成了高位元組資料存在低位址記憶體單元,低位元組資料存在高位址記憶體單元。

而在小端裝置上正好相反,資料是從低位元組資料開始的,所以就把低位元組資料的8位給了1-7這8根資料線,剩下的依次分配,最後在乙個時鐘週期內把這32位資料存到了記憶體裡,這樣就造成了高位元組資料存在高位址記憶體單元,低位元組資料存在低位址記憶體單元。

大家在進行網路程式設計中,傳送資料的時候資料使用的資料型別一定要和接收資料時資料使用的資料型別一樣,這樣才不會出現位元組序的問題,如果不一樣就有可能出現位元組序的問題,小端位元組序上肯定是沒問題的,但在大端上就有可能了,大家還需要注意一點,位元組序問題只會出現在涉及指標操作中,單純的賦值是不會出現位元組序的問題的,比如

int a = 0x12345678;

short b;

b = a;

這種情況是不會出現位元組序的問題的;

但是下面這種就有可能了

int a = 0x12345678;

short *ptr;

int b;

prt = (short *)&a;

b =*ptr;

網路程式設計中的網路位元組序與主機位元組序

一 主機位元組序 不同的cpu有不同的位元組序型別 這些位元組序是指整數在記憶體中儲存的順序 這個叫做主機序 最常見的有兩種 例子 在記憶體中雙字0x01020304 dword 的儲存方式 記憶體位址 4000 4001 4002 4003 le 04 03 02 01 be 01 02 03 0...

大小端 網路位元組序 本地位元組序問題

總結 1 80x86使用小端法 即本地位元組序 網路位元組序使用大端法。2 二進位制的網路程式設計中,傳送資料,最好以unsigned char,unsigned short,unsigned int 來處理,unsigned short unsigned short 以網路位元組序處理後再拷貝到傳...

UNIX網路程式設計中的位元組序問題

1 inet pton inet pton 將 點分十進位制 二進位制整數 int inet pton int af,const char src,void dst 這個函式轉換字串到網路位址,第乙個引數af是位址簇,第二個引數 src是 位址,第三個引數 dst接收轉換後的資料。af af ine...