1. 程式人生 > >Linux網絡編程--字節序

Linux網絡編程--字節序

-c bits 小端 %x 打印 string include 變量類型 pre


1 .談到字節序,那麽會有朋友問什麽是字節序
非常easy:【比如一個16位的整數。由2個字節組成,8位為一字節,有的系統會將高字節放在內存低的地址上,有的則將低字節放在內存高的地址上,所以存在字節序的問題。】


2 .那麽什麽是高字節、低字節?
也相當簡單:【一個16進制整數有兩個字節組成,比如:0xA9。


高字節就是指16進制數的前8位(權重高的8位),如上例中的A。


低字節就是指16進制數的後8位(權重低的8位),如上例中的9。


大於一個字節的變量類型一般有兩種表示方法:
技術分享
比如:變量0xabcd在大端字節序和小端字節型系統中表示方法如圖
技術分享
我們用代碼驗證一下我們自己的系統是小端還是大端吧
技術分享

#include <stdio.h>

/* 聯合類型的變量類型。用於測試字節序
*   成員value的高低端字節能夠由成員type按字節訪問
 */
typedef union{
    unsigned short int value;                               /*短整型變量*/
    unsigned char byte[2];                              /*字符類型*/
}to;

int main(int argc, char *argv)
{   
    to typeorder ;                                      /*一個to類型變量*/
typeorder.value = 0xabcd; /* 將typeorder變量賦值為0xabcd */ /* 小端字節序檢查 */ if(typeorder.byte[0] == 0xcd && typeorder.byte[1]==0xab){ /*低字節在前*/ printf("Low endian byte order" "byte[0]:0x%x,byte[1]:0x%x\n", typeorder.byte[0], typeorder.byte
[1]); } /* 大端字節序檢查 */ if(typeorder.byte[0] == 0xab && typeorder.byte[1]==0xcd){ /*高字節在前*/ printf("High endian byte order" "byte[0]:0x%x,byte[1]:0x%x\n", typeorder.byte[0], typeorder.byte[1]); } return 0; }

3 .字節序轉換函數介紹
技術分享

字節序轉換函數的使用:

#include <stdio.h>

/* 聯合類型的變量類型,用於測試字節序
*   成員value的高低端字節能夠由成員type按字節訪問
 */
/* 16位 */
typedef union{
    unsigned short int value;
    unsigned char byte[2];  
}to16;
/* 32位 */
typedef union{
    unsigned long int value;
    unsigned char byte[4];  
}to32;

#define BITS16 16   /*16位*/
#define BITS32 32   /*32位*/
/* 依照字節打印,begin為字節開始,
*  flag為BITS16表示16位,
*  flag為BITS32表示32位。 
*/
void showvalue(unsigned char *begin, int flag)
{
    int num = 0, i = 0;
    if(flag == BITS16){
        num = 2;    
    }else if(flag == BITS32){
        num = 4;    
    }

    for(i = 0; i< num; i++)
    {
        printf("%x ",*(begin+i));   
    }
    printf("\n");
}

int main(int argc, char *argv)
{   
    to16 v16_orig, v16_turn1,v16_turn2; /*一個to16類型變量*/
    to32 v32_orig, v32_turn1,v32_turn2; /*一個to32類型變量*/


    v16_orig.value = 0xabcd;        /* 賦值為0xabcd */
    v16_turn1.value = htons(v16_orig.value);/*第一次轉換*/
    v16_turn2.value = ntohs(v16_turn1.value);/*第二次轉換*/

    v32_orig.value = 0x12345678;    /* 賦值為0x12345678 */
    v32_turn1.value = htonl(v32_orig.value);/*第一次轉換*/
    v32_turn2.value = ntohl(v32_turn1.value);/*第二次轉換*/

    /* 打印結果 */
    printf("16 host to network byte order change:\n");  
    printf("\torig:\t");showvalue(v16_orig.byte, BITS16);   /* 16位數值的原始值 */
    printf("\t1 times:");showvalue(v16_turn1.byte, BITS16); /* 16位數值的第一次轉換後的值 */
    printf("\t2 times:");showvalue(v16_turn2.byte, BITS16); /* 16位數值的第二次轉換後的值 */

    printf("32 host to network byte order change:\n");
    printf("\torig:\t");showvalue(v32_orig.byte, BITS32);   /* 32位數值的原始值 */
    printf("\t1 times:");showvalue(v32_turn1.byte, BITS32); /* 32位數值的第一次轉換後的值 */
    printf("\t2 times:");showvalue(v32_turn2.byte, BITS32); /* 32位數值的第二次轉換後的值 */


    return 0;   
}

Linux網絡編程--字節序