不同cpu中,4位元組整數1在記憶體空間的儲存方式是不同的。4位元組整數1可用2進製表示如下:
00000000 00000000 00000000 00000001
有些cpu以上面的順序儲存到記憶體,另外一些cpu則以倒序儲存,如下所示:
00000001 00000000 00000000 00000000
若不考慮這些就收發資料會發生問題,因為儲存順序的不同意味著對接收資料的解析順序也不同。cpu向記憶體儲存資料的方式有兩種:
僅憑描述很難解釋清楚,不妨來看乙個例項。假設在 0x20 號開始的位址中儲存4位元組 int 型資料 0x12345678,大端序cpu儲存方式如下圖所示:
圖1:整數 0x12345678 的大端序位元組表示
對於大端序,最高位位元組 0x12 存放到低位位址,最低位位元組 0x78 存放到高位位址。小端序的儲存方式如下圖所示:
圖2:整數 0x12345678 的小端序位元組表示
不同cpu儲存和解析資料的方式不同(主流的intel系列cpu為小端序),小端序系統和大端序系統通訊時會發生資料解析錯誤。因此在傳送資料前,要將資料轉換為統一的格式——網路位元組序(network byte order)。網路位元組序統一為大端序。
主機a先把資料轉換成大端序再進行網路傳輸,主機b收到資料後先轉換為自己的格式再解析。在《
使用bind()和connect()函式
》一節中講解了 sockaddr_in 結構體,其中就用到了網路位元組序轉換函式,如下所示:
//建立sockaddr_in結構體變數
struct
sockaddr_in serv_addr;
memset
(&serv_addr,0,
sizeof
(serv_addr));
//每個位元組都用0填充
serv_addr.sin_family = af_inet;
//使用ipv4位址
serv_addr.sin_addr.s_addr =
inet_addr
("127.0.0.1"
);//具體的ip位址
serv_addr.sin_port =
htons
(1234
);//埠號
htons() 用來將當前主機位元組序轉換為網路位元組序,其中h
代表主機(host)位元組序,n
代表網路(network)位元組序,s
代表short,htons 是 h、to、n、s 的組合,可以理解為」將short型資料從當前主機位元組序轉換為網路位元組序「。
常見的網路位元組轉換函式有:
通常,以s
為字尾的函式中,s
代表2個位元組short,因此用於埠號轉換;以l
為字尾的函式中,l
代表4個位元組的long,因此用於ip位址轉換。
舉例說明上述函式的呼叫過程:
#include
#include
#include
#pragma
comment
(lib,
"ws2_32.lib"
)int
main
()
執行結果:
host ordered port: 0x1234
network ordered port: 0x3412
host ordered address: 0x12345678
network ordered address: 0x78563412
另外需要說明的是,sockaddr_in 中儲存ip位址的成員為32位整數,而我們熟悉的是點分十進位制表示法,例如 127.0.0.1,它是乙個字串,因此為了分配ip位址,需要將字串轉換為4位元組整數。
inet_addr() 函式可以完成這種轉換。inet_addr() 除了將字串轉換為32位整數,同時還進行網路位元組序轉換。請看下面的**:
#include
#include
#include
#pragma
comment
(lib,
"ws2_32.lib"
)int
main
()else
conv_addr =
inet_addr
(addr2);
if(conv_addr == inaddr_none)
else
system
("pause"
);return0;
}
執行結果:
network ordered integer addr: 0x4030201
error occured!
從執行結果可以看出,inet_addr() 不僅可以把ip位址轉換為32位整數,還可以檢測無效ip位址。
注意:為 sockaddr_in 成員賦值時需要顯式地將主機位元組序轉換為網路位元組序,而通過 write()/send() 傳送資料時tcp協議會自動轉換為網路位元組序,不需要再呼叫相應的函式。
大端位元組序 小端位元組序(網路位元組序 主機位元組序)
大端位元組序 整數的高位位元組儲存在記憶體的低位址處,低位元組儲存在記憶體的高位址處。一般pc大多採用小端位元組序,也稱為主機位元組序。網路上傳輸採用大端位元組序,也稱為網路位元組序。linux中常用轉換函式如下 include uint32 t htonl uint32 t hostlong 無符...
TCP IP 大端 小端位元組序,網路位元組序
不同的cpu有不同的位元組序型別 這些位元組序是指整數在記憶體中儲存的順序 這個叫做主機序 最常見的有兩種 1 little endian 將低序位元組儲存在起始位址 2 big endian 將高序位元組儲存在起始位址 最符合人的思維的位元組序 位址低位儲存值的低位 位址高位儲存值的高位 怎麼講是...
大端模式小端模式以及網路位元組序
大端模式小端模式以及網路位元組序 主機位元組序有兩種 大端模式和小端模式 不同的cpu有不同的主機位元組序型別。典型的使用小端儲存的cpu有 intel x86和arm 典型的使用大端儲存cpu有 power pc mips unix和hp paunix。網路位元組序類似於大端模式,注意是類似,為什...