我們在做網路相關的程式設計時,經常會遇到網路位元組序和主機位元組序的問題:當我們要把資料傳送到網路中進行傳輸時,需要把資料先轉換為網路位元組序再傳送;當我們從網路中接收到資料後,需要先轉換為主機位元組序才能使用。
位元組序是計算機體系結構的乙個基本屬性,每台計算機都是按照自己的位元組序方式處理資料的。那到底什麼是位元組序呢?簡單的說,位元組序是計算機處理資料時,對記憶體中資料的高位和低位進行判定的方法。位元組序有兩種,即大端位元組序(big endian)和小端位元組序(little endian)。位元組序是與計算機的體系結構相關的。我們平常使用的x86平台使用的是小端位元組序,而ibm的powerpc平台使用的是大端位元組序。
我們知道,cpu通過並行的資料匯流排訪問記憶體。當cpu向記憶體讀取資料時,首先記憶體中對應位中的資料被讀到資料匯流排上,然後資料匯流排上的資料被儲存到cpu 內部的暫存器中。每一根資料匯流排把記憶體中的一位資料傳遞到cpu暫存器中的一位,因此記憶體位與暫存器位存在對應關係。從暫存器位與記憶體位的對應方式可以方便的判斷一台計算機所使用的位元組序。
圖1 小端位元組序
圖 1中的cpu暫存器是32位的。暫存器的最左側是最低位(lsb,least significant bit),最右側是最高位(msb, most significant bit)。對應到記憶體中可知,記憶體的低位址位元組是低位,高位址位元組是高位。按照位址順序乙個位元組乙個位元組的讀出記憶體中的資料,我們得到0x09, 0x48, 0x14, 0x42(注意,在位元組內部,高位仍然在右邊)。但是把這4個位元組合在一起作為乙個整數讀出來,結果是0x42144809。這種把低位放在低位址位元組的位元組序就是小端位元組序。
圖2 大端位元組序
與小端位元組序相對的就是大端位元組序。與圖1相反,圖2中的32位暫存器中,最左側是最高位,最右側是最低位。圖2記憶體中的資料與圖1記憶體中的資料(按位位址排列)完全相同,但是按照位元組乙個乙個的讀出為0x90, 0x12, 0x24, 0x42,而把這4個位元組合在一起作為乙個整數讀出來,結果是0x90122442。
2013-8 :現在看來,把位元組序問題理解為cpu暫存器和記憶體位址之間的對映,貌似有點不太合適,不過當時確實為我提供了位元組序的一種理解方法
由於不同體系架構的裝置使用的位元組序不同,當他們之間聯網互相傳送資料時,就會產生混亂。例如要傳送乙個32位的整數,有的裝置按照從最低位位元組到最高位位元組的順序依次傳送每一位資料,有的裝置按照從最高位到最低位的順序依次傳送每一位資料。為了統一這種混亂,現行標準規定,所有資料在網路中傳輸時按照從最高位到最低位的順序依次傳送每一位資料。
網路裝置在傳送和接收資料時以位元組(octect)為單位。在傳送和接收單個位元組時,網路裝置總是按照從高位到低位的順序傳送和接收位元組資料。
網路裝置傳送和接收乙個位元組時,能夠保證順序正確,所以位元組內部的順序在通訊過程中不用考慮。
對於小端位元組序主機如圖1,這就意味著從右到左的順序傳送每一位;對於大端位元組序主機如圖2,這就意味著從左到右的順序傳送每一位。接收端也按照這個順序接收位元組中的每一位。不論雙方各自的本地位元組序為何,單位元組資料的取值在傳輸前後不會發生改變。例如,圖1中位址0x0100中的資料在傳輸到大端位元組序或者小端位元組序的主機後,取值仍然是0x09。
假設網絡卡要傳送圖1記憶體中從0x0100開始的4位元組資料,網絡卡並不知道這4位元組的資料是作為乙個整數,或者僅僅是普通的位元組序列。網絡卡簡單的先把第乙個位元組0x09傳送出去,再把第二個位元組0x48傳送出去,然後是0x14和0x42。接收端網絡卡先收到0x09,假設把它儲存在位址0x0200中;然後接收到0x48,把它儲存到位址0x0201中;然後是0x14和0x42,分別儲存在位址0x0202和0x0203中。
如果上述4個位元組僅僅是普通的位元組序列,那麼在傳輸前後,位元組序列的順序和取值並沒有變化,沒有問題。如果上述4個位元組是乙個整數,上述傳送順序違背了現行標準
那麼在大端位元組序的主機和小端位元組序的主機上來解釋上述數值,會得出不同的數字。因此,不同位元組序主機之間通訊時,需要約定一種傳輸順序,主機需要將上述資料的位元組順序調整為上述傳輸順序後再傳送。調整之前的順序是資料在本地的表示,稱作主機位元組序;調整之後的順序是資料在傳輸時的順序,稱作網路位元組序。目前的網路位元組序為大端位元組序。調整之後的資料在記憶體中的儲存情況如圖3所示。
圖3 小端位元組序:按網路位元組序排列
在大端位元組序主機上,網路位元組序和主機位元組序是相同的;在小端位元組序主機上,網路位元組序和主機位元組序是不同的。
如果資料不滿乙個位元,那麼使用時需要特別小心。例如如下定義的乙個結構:
如果在大端位元組序主機上編譯,那麼high_bits的確是高4位,low_bits的確是低4位;如果在小端位元組序主機上編譯,那麼情況就恰恰相反了。
大端位元組序 小端位元組序(網路位元組序 主機位元組序)
大端位元組序 整數的高位位元組儲存在記憶體的低位址處,低位元組儲存在記憶體的高位址處。一般pc大多採用小端位元組序,也稱為主機位元組序。網路上傳輸採用大端位元組序,也稱為網路位元組序。linux中常用轉換函式如下 include uint32 t htonl uint32 t hostlong 無符...
位元組序和網路位元組序
1 位元組序 由於不同的計算機系統採用不同的位元組序儲存資料,同樣乙個4位元組的32位整數,在記憶體中儲存的方式就不同.位元組序分為小尾位元組序 little endian 和大尾位元組序 big endian intel處理器大多數使用小尾位元組序,motorola處理器大多數使用大尾 big e...
位元組序和網路位元組序
1位元組序 由於不同的計算機系統採用不同的位元組序儲存資料,同樣乙個4位元組的32位整數,在記憶體中儲存的方式就不同.位元組序分為小尾位元組序 little endian 和大尾位元組序 big endian intel處理器大多數使用小尾位元組序,motorola處理器大多數使用大尾 big en...