英文版發表在:holmeshe.me
我在讀一些網路系統的原始碼時,htons()和 ntohs() 是兩個最開始困擾我的函式。所以我決定要重新學一下大學裡的知識-位元組序。
位元組序控制了乙個字(word)是怎麼儲存在記憶體裡,以及怎麼在網路上傳輸的。在big-endian中,最高位的byte被儲存在最低的位址,而在little-endian中,最高位則存在最高的位址。
正著
反著在物理媒介上放位元組和鋪地板一樣,正著鋪或者反著鋪都可以。但是乙個系統設計師就需要做個決定,來保證風格一致了。rfc 1700裡面規定,網路協議裡面都使用big-endian 位元組序,但是一些主機的設計師明顯不同意。x86使用little-endian;而arm則兩種都有可能。這就意味著同乙個資料,在不同的系統中存放的實際值是不一樣的。比如說,a1b2c3d4 (寫成十進位制是 2712847316)就會有兩種存放方式,
在上圖中,每乙個框,比如那個a1 的框,代表乙個位元組。這裡要注意,這個字「節序」是以「位元組」 (byte)而不是位(bit)為單位的。
其實計算機處理兩種位元組序都可以,但是人類就總會抱怨little-endian反了。為啥呢?難道把低位位元組設定給低位址,高位位元組給高位址不是最合乎邏輯的做法嗎?
其實,這個是因為我們在紙上(另一種物理媒介)寫這些數字時會在潛意識裡用big-endian。還是那上面的數字舉例(a1b2c3d4),我們的潛意識會在這個數字周圍畫上橫縱座標,
如果我們指揮潛意識從右往左畫這個橫座標,也許我們就可以解決這個直覺和理性之間的矛盾了。
我覺得這麼做也沒啥不對的,畢竟在實際開發中本來就存在各種各樣的座標系,比如:
你覺得呢?
好了,下面我們來看看為啥這些理論這麼重要,並且在實際中都是咋使用的。
這兩個函式就是用來解決網路和主機位元組序不一致的問題。技術上來說,當主機在網路上通訊時,這兩個函式負責轉換主機和網路位元組序。如果主機和網路位元組序是一樣的(這代表主機和網路都用big-endian),這兩個函式啥都不做。而當主機和網路位元組序不一致的話,htons() 把little-endian轉換成big-endian,而ntohs()把big-endian轉換回為little-endian。
類似的還有一對函式,htonl()和ntohl()。這兩個函式除了處理的數字比較大以外,其他的都和htons(),ntohs()一樣,就不贅述了。
#include #define bits_per_byte 8
int main()
printf("\n");
unsigned int anint_net = htons(anint);
truth = &anint_net;
printf("value in decimal after hton: %u\n", anint_net);
printf("0x");
for (int i = 0; i < sizeof(anint_net); i++)
printf("\n");
}
結果是(在我的測試機上):
value in decimal: 2712847316
0xd4c3b2a1
value in decimal after hton: 54467
0xc3d40000
正如上述��,htons()把anint的原始的值轉換成big-endian,用於準備網路傳輸。這個值會在接收方用ntohs()恢復成原始值。雖然這個接受方的部分沒有展示,但是我相信你可以懂的。
我們可以復用上面��中的**來實現乙個函式來判斷主機的位元組序:
int islittle()
實際上還有乙個更簡單的辦法,
cpu | grep "byte order"
網路基礎知識 網路位元組序與主機位元組序
多位元組的數值在記憶體中高低位的排列方式會影響所表示的數值。根據位元組高低位排序方式的不同,可以分為 大端位元組序 big endian 和 小端位元組序 little endian 大端位元組序是指乙個整數的高位位元組儲存在記憶體的低位址處,可以理解為數值的高位部分靠前儲存。以0x12343abc...
位元組序和網路位元組序
1 位元組序 由於不同的計算機系統採用不同的位元組序儲存資料,同樣乙個4位元組的32位整數,在記憶體中儲存的方式就不同.位元組序分為小尾位元組序 little endian 和大尾位元組序 big endian intel處理器大多數使用小尾位元組序,motorola處理器大多數使用大尾 big e...
位元組序和網路位元組序
1位元組序 由於不同的計算機系統採用不同的位元組序儲存資料,同樣乙個4位元組的32位整數,在記憶體中儲存的方式就不同.位元組序分為小尾位元組序 little endian 和大尾位元組序 big endian intel處理器大多數使用小尾位元組序,motorola處理器大多數使用大尾 big en...