socket程式設計 位元組序

2021-07-10 04:44:53 字數 1698 閱讀 8401

接觸到socket程式設計,就一定會接觸位元組序轉換。

對於字串來說,是沒有位元組序的差別的,就像我們寫字,記憶體就像是紙,字串就從左向右依次寫:

記憶體資料:     'a'            'b'            'c'            'd'

而任何cpu讀取的時候,也都是從左向右依次讀取。

對於多位元組資料(比如short、int、long...),不同位元組序是有差別的。

所有x86架構cpu(包括x64)都是用的小端位元組序,網路位元組序是大端序:

int a = 0x01020304;

大端序a :    0x01        0x02        0x03        0x04            即cpu讀出的資料從高向低位寫入變數

小端序a :    0x04        0x03        0x02        0x01            即cpu讀出的資料從低向高位寫入變數

如果我們寫的程式不進行位元組序轉換會怎麼樣呢:

int a = 0x01020304;

在我們x86架構機器的記憶體裡,它是這樣寫的0x04030201(注意,這是它在記憶體裡的真實寫法,當我們的程式以int型讀取的時候才會轉化成0x01020304),此時進行網路傳送,send程式會以位元組的方式(可以把它想象成字串),一位元組一位元組的傳送,到了網路上,它的順序仍然是0x04030201(此時它的順序已經錯了)。當資料到達對端機器的時候,對端機器也是一位元組一位元組的收入記憶體,它的順序仍然是0x04030201。如果對端仍是x86架構,那麼資料讀出來的時候它又被轉化成了0x01020304,這看起來像是對的。但是如果對端是大端序的架構,那麼它的int型資料就變成了0x04030201。

位元組序轉換:

linux裡提供了現成的函式:htonl, ntohl ...       這是一系列函式,卻只提供了2位元組和4位元組的轉換。

判斷位元組序:

int is_big_endian(void)

函式雖然簡陋,但是已經夠用了。

位元組序轉換巨集,順便將數字轉換成陣列:

#define rhton16(h, n) 

#define rhton32(h, n)

#define rhton64(h, n)

陣列轉換成數字:

#define rntoh16(n) (((unsigned short)((n)[1])) | ((unsigned short)((n)[0])<<8))

#define rntoh32(n) (((unsigned int)((n)[3])) | ((unsigned int)((n)[2])<<8) | ((unsigned int)((n)[1])<<16) | ((unsigned int)((n)[0])<<24))

#define rntoh64(n) (((unsigned long)((n)[7])) | ((unsigned long)((n)[6])<<8) | ((unsigned long)((n)[5])<<16) | ((unsigned long)((n)[4])<<24) | ((unsigned long)((n)[3])<<32) | ((unsigned long)((n)[2])<<40) | ((unsigned long)((n)[1])<<48) | ((unsigned long)((n)[0])<<56))

socket程式設計之網路位元組序與主機位元組序

0 為什麼會有大小端模式之分呢?這是因為在計算機系統中,我們是以位元組為單位的,每個位址單元都對應著乙個位元組,乙個位元組為 8bit。但是在c語言中除了8bit的char之外,還有16bit的short型,32bit的long型,另外,對於位數大於 8位的處理器,例如16位或者32位的處理器,由於...

網路程式設計 位元組序

三 位址形式的轉換函式 當儲存多位元組資料時,就涉及到位元組序的概念。高位位元組儲存在低位址為大端對齊,低位位元組儲存在低位址為小端對齊。判斷系統為大端對齊還是小端對齊的方法 include typedef union data intmain int argc,char ar else if ob...

大端位元組序 小端位元組序(網路位元組序 主機位元組序)

大端位元組序 整數的高位位元組儲存在記憶體的低位址處,低位元組儲存在記憶體的高位址處。一般pc大多採用小端位元組序,也稱為主機位元組序。網路上傳輸採用大端位元組序,也稱為網路位元組序。linux中常用轉換函式如下 include uint32 t htonl uint32 t hostlong 無符...