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

Beej's Guide 系列連載 04:IP 位址、位元組序與 Socket 結構體

     編輯:關於C語言

IPv4 與 IPv6 位址格式

  • IPv4:32 位,點分十進制,如 192.0.2.111。
  • IPv6:128 位,冒號十六進制,如 2001:0db8:c9d2:aee5:73e3:934a:a5ae:9551。
  • IPv4 映射到 IPv6:::ffff:192.0.2.33。

子網遮罩

用於區分網路位與主機位。預設:A 類 255.0.0.0,B 類 255.255.0.0,C 類 255.255.255.0。CIDR 表示法如 /24。

埠號

IP 如飯店地址,Port 如房間號。知名埠:HTTP 80, HTTPS 443, SSH 22, DNS 53。

位元組序轉換

網路序為 Big-Endian,主機序視 CPU 而定(x86 為 Little-Endian)。必須轉換:

函式意義
htons()Host-to-Network Short (16 位)
htonl()Host-to-Network Long (32 位)
ntohs()Network-to-Host Short
ntohl()Network-to-Host Long

所有放入結構體的埠號、IP 位址必須先經 htons/htonl 轉換。

核心 Socket 結構體

struct addrinfo (通用、支援 IPv4/IPv6)

struct addrinfo {
    int              ai_flags;
    int              ai_family;     // AF_INET, AF_INET6, AF_UNSPEC
    int              ai_socktype;   // SOCK_STREAM, SOCK_DGRAM
    int              ai_protocol;   // 0, IPPROTO_TCP, IPPROTO_UDP
    size_t           ai_addrlen;
    struct sockaddr *ai_addr;
    char            *ai_canonname;
    struct addrinfo *ai_next;
};

用 getaddrinfo() 填充,取代舊式 gethostbyname。

struct sockaddr (通用基址)

struct sockaddr {
    sa_family_t  sa_family;  // AF_INET, AF_INET6
    char         sa_data[14]; // 協定位址 (含 port + IP)
};

struct sockaddr_in (IPv4 專用)

struct sockaddr_in {
    sa_family_t    sin_family; // AF_INET
    in_port_t      sin_port;   // 已為網路序
    struct in_addr sin_addr;   // 32 位 IP
    unsigned char  sin_zero[8]; // 填充對齊
};
struct in_addr { uint32_t s_addr; };

struct sockaddr_in6 (IPv6 專用)

struct sockaddr_in6 {
    sa_family_t     sin6_family;   // AF_INET6
    in_port_t       sin6_port;
    uint32_t        sin6_flowinfo;
    struct in6_addr sin6_addr;     // 128 位 IP
    uint32_t        sin6_scope_id; // 介面索引
};
struct in6_addr { unsigned char s6_addr[16]; };

struct sockaddr_storage (通用儲存,足夠大)

struct sockaddr_storage {
    sa_family_t ss_family; // AF_INET or AF_INET6
    char        __ss_padding[128-sizeof(sa_family_t)];
    __ss_align;            // 強制對齊
};

用於 accept()、recvfrom() 等不確定 IPv4/IPv6 的場合,再根據 ss_family 轉型。

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