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

C 語言實戰:Socket 位址轉換與位元組序處理 (htonl/ntohl 系列)

     編輯:關於C

前言

AF_INET 域 Socket 通訊涉及不同機器架構的位元組序差異:網路傳輸統一用大端序,主機序視 CPU 而定(x86 為小端)。系統提供四大轉換函式自動處理,本文詳細解析用法並實測驗證。

四大轉換函式

函式意義資料型別
htonlHost TO Network Longuint32_t (32-bit)
htonsHost TO Network Shortuint16_t (16-bit)
ntohlNetwork TO Host Longuint32_t
ntohsNetwork TO Host Shortuint16_t

標頭檔:<arpa/inet.h>(Linux/macOS)或 <winsock2.h>(Windows)。
智慧特性:若主機序已為大端,函式內部不實際轉換,直接回傳原值。

實戰範例:驗證位元組序轉換

#include 
#include   // Linux/macOS
// #include   // Windows 需連結 ws2_32.lib

void print_bytes(const char *label, const void *data, size_t len) {
    const unsigned char *p = data;
    printf("%s\n", label);
    for (size_t i = 0; i < len; ++i)
        printf("[%p] = 0x%02x\n", p + i, p[i]);
    puts("");
}

int main() {
    uint32_t host_val = 0x12345678;
    print_bytes("主機序 (Host Order):", &host_val, sizeof(host_val));

    uint32_t net_val = htonl(host_val);
    print_bytes("網路序 (Network Order):", &net_val, sizeof(net_val));

    uint32_t back_val = ntohl(net_val);
    print_bytes("轉回主機序:", &back_val, sizeof(back_val));
    return 0;
}

執行結果解析 (小端機器)

主機序 (Host Order):
[0x7ffc...] = 0x78
[0x7ffc...] = 0x56
[0x7ffc...] = 0x34
[0x7ffc...] = 0x12

網路序 (Network Order):
[0x7ffc...] = 0x12
[0x7ffc...] = 0x34
[0x7ffc...] = 0x56
[0x7ffc...] = 0x78

轉回主機序:
[0x7ffc...] = 0x78
[0x7ffc...] = 0x56
[0x7ffc...] = 0x34
[0x7ffc...] = 0x12

明顯可見:主機序為小端(低位在低址),網路序為大端(高位在低址),htonl 正確完成雙向轉換。

實務應用模式

填寫 sockaddr_in 結構

struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(8080);           // 連接埠必須轉網路序
addr.sin_addr.s_addr = htonl(INADDR_ANY); // IP 位址轉網路序 (INADDR_ANY=0 無影響)

解析收到的封包

uint16_t peer_port = ntohs(addr.sin_port);
uint32_t peer_ip = ntohl(addr.sin_addr.s_addr);

常見錯誤與避坑

  1. 忘記轉換連接埠:sin_port 必須用 htons,否則大端機器上連線失敗。
  2. 重複轉換:已為網路序的資料再呼叫 htonl 會導致雙重反轉。
  3. 直接存取結構成員不轉換:sin_addr.s_addr 需用 htonl/ntohl,勿直接指派主機序整數。
  4. Windows 需初始化 Winsock:呼叫 WSAStartup 並連結 ws2_32.lib。

總結

位元組序轉換是跨平台網路程式的基石。善用 htonl/htons/ntohl/ntohs,配合 getaddrinfo 等現代 API,可寫出可攜、健壯的 Socket 程式。

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