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

Linux 網絡編程基礎:大端小端模式與字節序轉換詳解

     編輯:關於C語言

什麼是大端與小端模式?

計算機內存中多字節數據的存儲順序稱為字節序:

  • 大端模式:高位字節存放在低地址(符合人類閱讀習慣)。網絡傳輸標準採用大端序,稱為網絡字節序。
  • 小端模式:低位字節存放在低地址。x86 架構 CPU 採用小端序,稱為主機字節序。

例:32 位整數 0x12345678 在內存中的分布:

地址偏移大端模式小端模式
0x000x12 (高字節)0x78 (低字節)
0x010x340x56
0x020x560x34
0x030x78 (低字節)0x12 (高字節)

主機序與網絡序轉換實戰

實例 1:點分十進制 IP 轉主機字節序整數

IP 180.97.33.107 → 十六進制 0xB461216B(網絡序)。主機為小端,內存中實際存儲為 0x6B2161B4。

#include <stdio.h>
#include <string.h>

int ip_to_host(const char *ip_str) {
    unsigned char bytes[4];
    sscanf(ip_str, "%hhu.%hhu.%hhu.%hhu", &bytes[0], &bytes[1], &bytes[2], &bytes[3]);
    // 手動構造主機序整數(小端:低地址存低字節)
    return (bytes[3] << 24) | (bytes[2] << 16) | (bytes[1] << 8) | bytes[0];
}

int main() {
    const char *ip = "180.97.33.107";
    int host_val = ip_to_host(ip);
    printf("IP: %s\nHost order (hex): %x\n", ip, host_val); // 輸出 6b2161b4
    return 0;
}

實例 2:主機序轉網絡序(手動實現 htonl)

// 方法一:指針交換字節
unsigned int htonl_v1(unsigned int host) {
    unsigned char *p = (unsigned char *)&host;
    unsigned char tmp;
    tmp = p[0]; p[0] = p[3]; p[3] = tmp;
    tmp = p[1]; p[1] = p[2]; p[2] = tmp;
    return host;
}

// 方法二:位運算(推薦,無類型懲罰風險)
unsigned int htonl_v2(unsigned int host) {
    return ((host & 0xFF) << 24) |
           ((host >> 8 & 0xFF) << 16) |
           ((host >> 16 & 0xFF) << 8) |
           (host >> 24 & 0xFF);
}

實例 3:網絡序轉點分十進制(手動實現 inet_ntoa)

char *net_to_ip_str(unsigned int net) {
    static char buf[16];
    sprintf(buf, "%u.%u.%u.%u",
            (net >> 24) & 0xFF,
            (net >> 16) & 0xFF,
            (net >> 8) & 0xFF,
            net & 0xFF);
    return buf;
}

系統標準函數

實際開發中應直接使用標準庫函數,保證可移植性:

  • inet_aton():字符串 IP → 網絡序 in_addr
  • inet_ntoa():網絡序 in_addr → 字符串 IP
  • htonl() / ntohl():32 位主機序↔網絡序
  • htons() / ntohs():16 位主機序↔網絡序

檢測當前主機字節序

int is_little_endian() {
    union { int i; char c[4]; } u = {1};
    return u.c[0] == 1; // 低地址存低字節即為小端
}

面試經典題

int a = 0x61; // 97
printf("%x\n", *(char *)&a); // 輸出 61 → 小端機

輸出低字節 0x61 證明為小端存儲。

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