socket網路位元組序以及大端序小端序

2021-07-12 07:05:46 字數 2558 閱讀 8769

不同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。網路位元組序類似於大端模式,注意是類似,為什...