網路傳輸的大小端-計算機網路複習筆記

fatKid發表於2020-11-06

網路傳輸的大小端-計算機網路複習筆記

大端模式:是指資料的高位元組儲存在記憶體的低地址中,而資料的低位元組儲存在記憶體的高地址中,地址由小向大增加,而資料從高位往低位放;
小端模式:是指資料的高位元組儲存在記憶體的高地址中,而資料的低位元組儲存在記憶體的低地址中,高地址部分權值高,低地址部分權值低,和我們的日常邏輯方法一致。

什麼是大小端?

大端模式:是指資料的高位元組儲存在記憶體的低地址中,而資料的低位元組儲存在記憶體的高地址中,地址由小向大增加,而資料從高位向低位存放。這樣的儲存模式有點兒類似於把資料當作字串順序處理:地址由小向大增加,而資料從高位往低位放;這和我們的閱讀習慣一致。

例子:
0000430: e684 6c4e 0100 1800 53ef 0100 0100 0000
0000440: b484 6c4e 004e ed00 0000 0000 0100 0000
在大端模式下,前32位應該這樣讀: e6 84 6c 4e ( 假設int佔4個位元組)
記憶方法: 地址的增長順序與值的增長順序相反

小端模式:是指資料的高位元組儲存在記憶體的高地址中,而資料的低位元組儲存在記憶體的低地址中,高地址部分權值高,低地址部分權值低

例子:
0000430: e684 6c4e 0100 1800 53ef 0100 0100 0000
0000440: b484 6c4e 004e ed00 0000 0000 0100 0000
在小端模式下,前32位應該這樣讀: 4e 6c 84 e6( 假設int佔4個位元組)
記憶方法: 地址的增長順序與值的增長順序相同

為什麼會有大小端模式

計算機系統中是以位元組為單位的,每個地址單元都對應著一個位元組,一個位元組為8bit,但是在程式語言中,還存在著單位容量大於8位元組的變數如16bit的short,32位的int(具體看編譯器),另外,對於位數大於 8位的處理器,例如16位或者32位的處理器,由於暫存器寬度大於一個位元組,那麼必然存在著一個如何將多個位元組安排的問題。因此就導致了大端儲存模式和小端儲存模式。

例如:一個16bit的short型x,在記憶體中的地址為0x0010,x的值為0x1122,那麼大端模式下對於short型x,將0x11放在低地址中,即0x0010中,0x22放在高地址中,即0x0011中,小端模式則剛好相反。

X86結構是小端模式,而KEIL C51則為大端模式。很多的ARM,DSP都為小端模式。有些ARM處理器還可以隨時在程式中(在ARM Cortex 系列使用REV、REV16、REVSH指令 )進行大小端的切換。

不同模式下的資料傳輸問題

不同 CPU 儲存和解析資料的方式不同(主流的 Intel 系列 CPU 為小端序),小端序系統和大端序系統通訊時會發生資料解析錯誤。因此在傳送資料前,要將資料轉換為統一的格式——網路位元組序(Network Byte Order)。網路位元組序統一為大端序

判斷機器大小端

利用指標強制型別轉換

#include<stdio.h>  
int main()  
{  
    int a = 1;  
    char * p = (char*)&a;  
    if (*p == 1)  
    {  
        printf("little-endian");  
    }  
    else  
    {  
        printf("big-endian");  
    }  
    return 0;  
}  

如果小端方式中(i佔至少兩個位元組的長度)則i所分配的記憶體最小地址那個位元組中就存著1,其他位元組是0;大端的話則1在i的最高地址位元組處存放。char是一個位元組,所以強制將char型量p指向i則p指向的一定是i的最低地址,那麼就可以判斷p中的值是不是1來確定是不是小端。

聯合體

#include <stdio.h>
int main(void)
{
    union ppt{
         int a;
        unsigned char b[2];
    }dl;
    dl.a=0x1234;
    if(dl.b[0]==0x12)
    {
        printf("大端\n");
    }
    else{
        printf("小端!\n");
    }
 
    return 0;

相關文章