首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Socket 程式設計核心:位元組序轉換與大小端判斷

     編輯:關於C語言

Socket 程式設計核心:位元組序轉換與大小端判斷

字串 vs 多位元組資料

字串在記憶體中按字元順序儲存,CPU 讀取順序一致,無位元組序問題。但 short、int、long 等多位元組型別,不同架構儲存順序不同:

  • 大端序:高位元組存低位址(網路位元組序標準)
  • 小端序:低位元組存低位址(x86/x64 架構)

例:int a = 0x01020304
大端記憶體:01 02 03 04
小端記憶體:04 03 02 01

不轉換的後果

若雙端皆為 x86,因雙重反轉(寫入反序、讀取反序)結果看似正確;但一旦對端為大端架構(如某些網路設備、PowerPC),資料將被錯誤解讀。跨平台網路通訊必須統一為網路位元組序(大端)。

系統提供的轉換函數

#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong);   // host to network long
uint16_t htons(uint16_t hostshort);  // host to network short
uint32_t ntohl(uint32_t netlong);    // network to host long
uint16_t ntohs(uint16_t netshort);   // network to host short

僅支援 2/4 位元組,8 位元組需自行實作。

編譯期判斷大小端

int is_big_endian(void) {
    int test = 0x12345678;
    char *p = (char*)&test;
    return (*p == 0x12);
}

通用巨集:整數 ⇄ 位元組陣列(支援 2/4/8 位元組)

// 整數轉位元組陣列(大端序)
#define rhton16(h, n) do { (n)[0]=((h)>>8)&0xFF; (n)[1]=(h)&0xFF; } while(0)
#define rhton32(h, n) do { (n)[0]=((h)>>24)&0xFF; (n)[1]=((h)>>16)&0xFF; \
                           (n)[2]=((h)>>8)&0xFF;  (n)[3]=(h)&0xFF; } while(0)
#define rhton64(h, n) do { (n)[0]=((h)>>56)&0xFF; (n)[1]=((h)>>48)&0xFF; \
                           (n)[2]=((h)>>40)&0xFF; (n)[3]=((h)>>32)&0xFF; \
                           (n)[4]=((h)>>24)&0xFF; (n)[5]=((h)>>16)&0xFF; \
                           (n)[6]=((h)>>8)&0xFF;  (n)[7]=(h)&0xFF; } while(0)

// 位元組陣列轉整數(大端序)
#define rntoh16(n) (((n)[0]<<8)|(n)[1])
#define rntoh32(n) (((n)[0]<<24)|((n)[1]<<16)|((n)[2]<<8)|(n)[3])
#define rntoh64(n) ( ((uint64_t)(n)[0]<<56) | ((uint64_t)(n)[1]<<48) | \
                     ((uint64_t)(n)[2]<<40) | ((uint64_t)(n)[3]<<32) | \
                     ((uint64_t)(n)[4]<<24) | ((uint64_t)(n)[5]<<16) | \
                     ((uint64_t)(n)[6]<<8)  | (uint64_t)(n)[7] )

最佳實踐

  1. 發送前:htonl/htons 或自訂巨集轉為網路序
  2. 接收後:ntohl/ntohs 或自訂巨集轉為主機序
  3. 協定定義時明確標註欄位位元組序

掌握位元組序轉換是編寫健壯跨平台網路程式的基礎功夫。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved