網路位元組序和本地位元組序的理解和實現

2021-08-14 18:34:10 字數 2970 閱讀 6413

工作中經常用到這兩個概念,看了apue關於大端模式和小端模式的說明,和博文:htonl、ntohl、htons、ntohs函式實現 在這裡概括歸納一下,權當備忘。以下所有假設都是在32位x86系統上。 

大端模式:網路位元組序採用的模式,tcp/ip協議棧支援的模式 

小端模式:linux主機採用小端模式儲存。

這裡要注意不管是大端還是小端儲存,msb(資料最高位元組)始終是在最左邊,lsb(資料最低位元組)始終是在最右邊

比如以十六進製制的0x12345678為例,首先要了解十六進製制一位表示4個二進位制位,所以這個代表乙個32位(8*4),4位元組的資料,0x12是msb,0x78是lsb

對於大端模式msb儲存在低位位元組位址n,lsb儲存在高位位元組位址n+3,這裡的位元組位址也是32位的,資料按照位址偏移按單位元組存放。 

所以要將乙個字元指標char* cp強制轉換為這個整形位址,由於位元組序的不同會帶來差異。在小端機器上cp[0]指向最低位位址,存放的是0x78,然而cp[3]指向最高位位址,存放的是0x12;大端反之。 

可以用gdb除錯檢視,記憶體內部的變數分布,gdb記憶體檢視命令: 

x /nfu addr

說明 x 是 examine 的縮寫 

n表示要顯示的記憶體單元的個數 

f表示顯示方式, 可取如下值 

x 按十六進製制格式顯示變數。 

d 按十進位制格式顯示變數。 

u 按十進位制格式顯示無符號整型。 

o 按八進位制格式顯示變數。 

t 按二進位制格式顯示變數。 

a 按十六進製制格式顯示變數。 

i 指令位址格式 

c 按字元格式顯示變數。 

f 按浮點數格式顯示變數。 

u表示乙個位址單元的長度 

b表示單位元組, 

h表示雙位元組, 

w表示四位元組, 

g表示八字節 

參考博文:gdb檢視記憶體區命令

小端模式記憶體檢視實驗:

int main(int arc, char* arg)

編譯:編譯必須加-g選項才能生成可除錯的檔案

gcc littleending.c -g -o littleending

除錯:(gdb)gdb ./littleending

(gdb)b 4

//原始檔第四行設定斷點

(gdb)r //執行程式

(gdb)p &a //列印變數位址

$1 = (unsingned int *)0xbffff543

(gdb)x 0xbffff543

//檢視記憶體單元內變數

0xbffff543: 0x12345678

(gdb) x /4xb 0xbffff543

//單位元組檢視4個記憶體單元變數的值

0xbffff543: 0x78

0x56

0x34

0x12

(gdb) x /1xb 0xbffff543

0xbffff543: 0x78

(gdb) x /2xb 0xbffff543

0xbffff543: 0x56

(gdb) x /3xb 0xbffff543

0xbffff543: 0x34

(gdb) x /4xb 0xbffff543

0xbffff543: 0x78

0x56

0x34

0x12

//可以看到記憶體最低位址單元存放的是資料的lsb 0x78

//顯然linux x86下是小端的存放方式

typedef

unsigned

short

int uint16;

typedef

unsigned

long

int uint32;

// 短整型大小端互換

#define biglittleswap16(a) ((((uint16)(a) & 0xff00) >> 8) | \

(((uint16)(a) & 0x00ff) << 8))

// 長整型大小端互換

#define biglittleswap32(a) ((((uint32)(a) & 0xff000000) >> 24) | \

(((uint32)(a) & 0x00ff0000) >> 8) | \

(((uint32)(a) & 0x0000ff00) << 8) | \

(((uint32)(a) & 0x000000ff) << 24))

// 本機大端返回1,小端返回0

int checkcpuendian()

c; c.i = 0x12345678;

//利用了聯合的記憶體分配規則,共享記憶體僅分配一種資料結構

return (0x12 == c.s[0]);

}// 模擬htonl函式,本機位元組序轉網路位元組序

unsigned

long

int t_htonl(unsigned

long

int h)

// 模擬ntohl函式,網路位元組序轉本機位元組序

unsigned

long

int t_ntohl(unsigned

long

int n)

// 模擬htons函式,本機位元組序轉網路位元組序

unsigned

short

int t_htons(unsigned

short

int h)

// 模擬ntohs函式,網路位元組序轉本機位元組序

unsigned

short

int t_ntohs(unsigned

short

int n)

網路位元組序和本地位元組序的理解和實現

工作中經常用到這兩個概念,看了apue關於大端模式和小端模式的說明,和博文 htonl ntohl htons ntohs函式實現 在這裡概括歸納一下,權當備忘。以下所有假設都是在32位x86系統上。大端模式 網路位元組序採用的模式,tcp ip協議棧支援的模式 小端模式 linux主機採用小端模式...

位元組序和網路位元組序

1 位元組序 由於不同的計算機系統採用不同的位元組序儲存資料,同樣乙個4位元組的32位整數,在記憶體中儲存的方式就不同.位元組序分為小尾位元組序 little endian 和大尾位元組序 big endian intel處理器大多數使用小尾位元組序,motorola處理器大多數使用大尾 big e...

位元組序和網路位元組序

1位元組序 由於不同的計算機系統採用不同的位元組序儲存資料,同樣乙個4位元組的32位整數,在記憶體中儲存的方式就不同.位元組序分為小尾位元組序 little endian 和大尾位元組序 big endian intel處理器大多數使用小尾位元組序,motorola處理器大多數使用大尾 big en...