位元組序與位元組對齊

2021-09-20 20:29:22 字數 2906 閱讀 9843

一.網路位元組序與主機位元組序

1.大端和小端儲存

大端(big endian):高位存低位址。符合人類的正常思維。網路位元組序採用大端(網路傳輸的是位元組流)。

小端(littile endian):低位存低位址。

如果將乙個32位的整數0x12345678存放到乙個整型變數(int)中,這個整型變數採用大端或者小端模式在記憶體中的儲存由下表所示。

---------------------------

位址偏移 大端模式 小端模式

0x00      12     78

0x01      34     56

0x02      56     34

0x03      78     12

---------------------------

如果將乙個16位的整數0x1234存放到乙個短整型變數(short)中。這個短整型變數在記憶體中的儲存在大小端模式由下表所示。

---------------------------

位址偏移 大端模式 小端模式

0x00      12     34

0x01      34     12

---------------------------

例:int main(int argc,char** ar**)

sparc平台上的輸出:

local order:

[0]: 0x12 addr:4290770212 //高位位元組存放在低位址處,則是大端法;

[1]: 0x34 addr:4290770213

[2]: 0x56 addr:4290770214

[3]: 0x78 addr:4290770215 //低位位元組存放在高位址處;

htonl order:

[0]: 0x12 addr:4290770212 //由此看出,主機位元組序與網路位元組一樣;

[1]: 0x34 addr:4290770213

[2]: 0x56 addr:4290770214

[3]: 0x78 addr:4290770215

x86平台上的輸出:

local order:

[0]: 0x78 addr:4289157020 //低位位元組存放在低位址處,則是小端法;

[1]: 0x56 addr:4289157021

[2]: 0x34 addr:4289157022

[3]: 0x12 addr:4289157023 //高位位元組存放在高位址處;

htonl order:

[0]: 0x12 addr:4289157020 //由此看出,主機位元組序與網路位元組不一樣;

[1]: 0x34 addr:4289157021

[2]: 0x56 addr:4289157022

[3]: 0x78 addr:4289157023

2.位元組序轉化使用htons()還是使用htonl()?還是兩者都不行?

首先這兩個函式不是隨便使用的,單位元組資料無需也不能轉化,2位元組資料只能使用htons()轉換,4位元組資料只能使用htonl()

原因:例子:對於2個short資料0x1234和0x5678,儲存如下

---------------------------

位址偏移 大端模式

0x00      12    

0x01      34   

0x02      56   

0x03      78   

如果使用long 轉化函式。傳送端假如為大端,則0x1234 0x5678使用htonl()轉化成網路位元組序後,任然為0x1234 0x5678;

接收端如果為小端,使用ntohl()轉化後變為0x5678,0x1234這兩個資料交換了位置。

---------------------------

位址偏移   小端模式

0x00         78

0x01         56    小端0x5678

0x02         34

0x03         12    小端0x1234

---------------------------

所以2位元組和4位元組的轉換不能混用。那麼問題來了,8位元組的double,怎麼轉換?

解答:如果當前主機為小端,接收時先使用ntohl()轉換前4位元組,再使用ntohl()轉換後4位元組,然後交換前後4位元組。

在使用socket傳輸類於t_wfstpmsg結構體的資料時,msg部分由於轉換時不確定資料型別,給轉換帶來了難度,所以一定要定義好msg的資料型別,方便轉換。msg最好能是字元。

轉化錯了會存在倒序的問題。

3.位元組對齊對位元組序的影響

如結構體

#pragma pack(4)

typedef struct am;

void main(void)

;unsigned char *p=(unsigned char *)(&a);

int i=0;

while(i<8)

;結構體為例#pragma pack(4)

1.各成員所在記憶體位址及所佔位元組(該計算與結構體無關):int 0:4;char 4,1;short 6:2,char 8:1   一共佔了9個位址空間

2.結構體有效對齊與成員中自身對齊最大的成員的有效對齊相同為:成員中最大的為4,指定對齊為4,故有效對齊為4(兩者中較小者),所以最後結構體所佔的記憶體空間一定是4的整數倍

3.所以結構體所佔的位元組數為 (9/4+1)*4=12   ,上述結構體與struct a;所佔的空間是一樣的。

計算結構體大小時回答3個問題:

1.各成員佔幾個位元組

2.各成員起始位址從**開始(由有效對齊值決定)

3.結構體所佔空間是幾的整數倍

struct a;

struct a;

struct a;

Linux 位元組序與位元組對齊優化

1.位元組序跟linux windows無關,是由cpu構架決定 同乙個cpu不管裝的是windows 或 linux 位元組序都是一樣的 2.位元組對齊 linux 全用 attribute packed 作用於結構體,類似於pragma packet 1 使用方法如下 typdef struct...

位元組對齊 位域 位元組序

測試環境 win 7 64bits,vmware workstation 12 pro,ubuntu 15.10 64bits,使用gcc version 5.2.1 20151010 include pragma pack 1 14,11,11 pragma pack 2 16,12,12 pra...

位元組序與網路位元組序

cpu向記憶體儲存資料的方式有2種,這意味著cpu解析資料的方式也分為2種 0x20號 0x21號 0x22號 0x23號 0x12 0x32 0x56 0x78 整數0x12345678,0x12是最高位位元組,0x78是最低位位元組。因此大端中先儲存最高位位元組0x12,小端序儲存方式如下 0x...