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

Linux 網絡編程核心系統調用:socket 地址結構與地址轉換函數詳解

     編輯:關於C語言

Socket 地址核心結構體

// 通用地址結構
struct sockaddr {
    sa_family_t sa_family;  // 地址族:AF_INET, AF_INET6
    char        sa_data[14]; // 協議地址(IP+端口)
};

// IPv4 專用結構(實際編程常用)
struct sockaddr_in {
    sa_family_t    sin_family; // AF_INET
    in_port_t      sin_port;   // 端口號(網絡序)
    struct in_addr sin_addr;   // IP 地址(網絡序)
    unsigned char  sin_zero[8]; // 填充,對齊到 sockaddr 大小
};

struct in_addr {
    in_addr_t s_addr; // 32 位 IPv4 地址(網絡序)
};

地址轉換核心函數

1. inet_aton / inet_ntoa(IPv4 專用)

#include <arpa/inet.h>

int inet_aton(const char *cp, struct in_addr *inp); // 字符串 → 網絡序 in_addr
char *inet_ntoa(struct in_addr in);                 // 網絡序 in_addr → 字符串

注意:inet_aton 將結果以網絡序(大端)寫入 inp->s_addr。在小端主機上直接打印 %x 會顯示字節反轉後的值,但實際內存中已是正確的網絡序。

示例:字符串 IP 轉網絡序整數

struct in_addr addr;
inet_aton("180.97.33.107", &addr);
printf("Network order: %x\n", addr.s_addr); // 輸出 b461216b(大端)
// 主機為小端,printf 讀取內存低字節在前,顯示 6b2161b4
// 實際網絡傳輸時會發送正確的大端序列

示例:網絡序整數轉字符串 IP

struct in_addr addr;
addr.s_addr = 0xb461216b; // 直接賦值網絡序值
printf("IP: %s\n", inet_ntoa(addr)); // 輸出 180.97.33.107

2. gethostbyname(域名解析,已過時但仍常見)

#include <netdb.h>

struct hostent *gethostbyname(const char *name);

hostent 結構包含:官方主機名 h_name、別名列表 h_aliases、地址類型 h_addrtype、地址長度 h_length、地址列表 h_addr_list(網絡序)。

完整解析示例

struct hostent *h = gethostbyname("www.baidu.com");
printf("Official name: %s\n", h->h_name);
for (char **alias = h->h_aliases; *alias; alias++)
    printf("Alias: %s\n", *alias);
for (char **addr = h->h_addr_list; *addr; addr++) {
    struct in_addr in = *(struct in_addr *)*addr; // 強轉後解引用
    printf("IP: %s\n", inet_ntoa(in));
}

現代替代方案:getaddrinfo

gethostbyname 不支持 IPv6、非線程安全。新代碼應使用 getaddrinfo(),支持雙棧、異步解析、線程安全。

實戰提示

  • 所有網絡傳輸的端口、IP 必須用 htons()/htonl() 轉為網絡序
  • sockaddr_in 初始化時務必 memset(&addr, 0, sizeof(addr)) 清零 sin_zero
  • 調試時用 printf("%x", addr.sin_addr.s_addr) 觀察網絡序值,而非主機序
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved