#include <arpa/inet.h>

#include <arpa/inet.h>

<arpa/inet.h>网络编程 核心头文件,提供 IP 地址转换字节序处理 功能,主要用于 IPv4/IPv6 套接字编程(Socket Programming)。


1. 核心功能

功能关键函数/宏用途
IP 地址转换inet_aton(), inet_addr(), inet_ntoa()IPv4 字符串 ↔ 二进制转换
现代 IP 转换inet_pton(), inet_ntop()支持 IPv4/IPv6 的可移植转换
字节序转换htons(), htonl(), ntohs(), ntohl()主机字节序 ↔ 网络字节序(大端序)

2. 详细函数解析

2.1 IP 地址转换(IPv4)

(1) inet_aton() - 字符串 → 二进制(推荐)

1
int inet_aton(const char *cp, struct in_addr *inp);
  • 功能:将点分十进制 IPv4 地址(如 "192.168.1.1")转换为 struct in_addr

  • 返回值:

    • 成功:1
    • 无效地址:0
  • 示例:

    1
    2
    3
    4
    5
    6
    #include <arpa/inet.h>

    struct in_addr addr;
    if (inet_aton("192.168.1.1", &addr)) {
    printf("Binary: 0x%x\n", addr.s_addr);
    }

(2) inet_addr() - 字符串 → 二进制(已废弃)

1
in_addr_t inet_addr(const char *cp);
  • 问题:无法区分 "255.255.255.255"(合法)和错误返回(INADDR_NONE)。
  • 替代方案:使用 inet_aton()inet_pton()

(3) inet_ntoa() - 二进制 → 字符串

1
char *inet_ntoa(struct in_addr in);
  • 注意:返回静态缓冲区,非线程安全!

  • 示例:

    1
    2
    3
    struct in_addr addr;
    addr.s_addr = 0xC0A80101; // 192.168.1.1
    printf("IP: %s\n", inet_ntoa(addr));

2.2 现代 IP 转换(IPv4/IPv6)

(1) inet_pton() - 字符串 → 二进制(可移植)

1
int inet_pton(int af, const char *src, void *dst);
  • 参数:

    • af:地址族(AF_INETAF_INET6)。
    • src:输入字符串(如 "192.168.1.1""::1")。
    • dst:输出缓冲区(struct in_addrstruct in6_addr)。
  • 返回值:

    • 成功:1
    • 无效格式:0
    • 错误:-1errno 设置)。
  • 示例:

    1
    2
    3
    4
    5
    struct in_addr ipv4;
    inet_pton(AF_INET, "192.168.1.1", &ipv4);

    struct in6_addr ipv6;
    inet_pton(AF_INET6, "::1", &ipv6);

(2) inet_ntop() - 二进制 → 字符串(可移植)

1
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
  • 参数:

    • size:目标缓冲区大小(INET_ADDRSTRLENINET6_ADDRSTRLEN)。
  • 返回值:

    • 成功:dst
    • 失败:NULLerrno 设置)。
  • 示例:

    1
    2
    3
    char str[INET6_ADDRSTRLEN];
    struct in6_addr ipv6 = IN6ADDR_LOOPBACK_INIT;
    inet_ntop(AF_INET6, &ipv6, str, sizeof(str)); // "::1"

2.3 字节序转换

函数含义示例
htons()Host to Network (16-bit)htons(80) → 大端序的 80(HTTP 端口)
htonl()Host to Network (32-bit)htonl(0xC0A80101) → 网络序 IP
ntohs()Network to Host (16-bit)ntohs(received_port)
ntohl()Network to Host (32-bit)ntohl(received_ip)

示例

1
2
uint16_t port = 80;
uint16_t net_port = htons(port); // 主机序 → 网络序

3. 关键结构体

IPv4 地址结构

1
2
3
struct in_addr {
in_addr_t s_addr; // 32-bit IP(二进制)
};

通用地址结构(用于 connect()/bind()

1
2
3
4
5
6
struct sockaddr_in {
sa_family_t sin_family; // AF_INET
in_port_t sin_port; // 端口(网络字节序)
struct in_addr sin_addr; // IP 地址
char sin_zero[8]; // 填充
};

4. 完整示例

将 IP 和端口转换为网络格式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <arpa/inet.h>
#include <stdio.h>

int main() {
// 1. 转换 IP
struct in_addr addr;
inet_pton(AF_INET, "192.168.1.1", &addr);

// 2. 转换端口
uint16_t port = htons(8080);

// 3. 构造 sockaddr_in
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_port = port;
server.sin_addr = addr;

printf("Server: %s:%d\n",
inet_ntoa(server.sin_addr),
ntohs(server.sin_port));

return 0;
}

5. 注意事项

  1. 线程安全:
    • inet_ntoa() 使用静态缓冲区,非线程安全!优先用 inet_ntop()
  2. IPv6 支持:
    • inet_pton()/inet_ntop() 是 IPv6 兼容的推荐方式。
  3. 错误处理:
    • 检查 inet_pton() 的返回值,无效输入可能导致崩溃。
  4. 字节序问题:
    • 所有网络传输的数据(如端口、IP)必须用 htons()/htonl() 转换。

6. 总结

<arpa/inet.h> 的核心用途:

  1. IP 字符串 ↔ 二进制:
    • IPv4:inet_aton(), inet_ntoa()(旧) → inet_pton(), inet_ntop()(新)。
    • IPv6:仅支持 inet_pton(), inet_ntop()
  2. 字节序转换:
    • htons(), htonl(), ntohs(), ntohl()

适用于 Socket 编程、服务器开发、网络工具(如 pingtraceroute)。