Linux Socket 编程核心:深入解析 sockaddr 数据结构族
以下是关于 Linux Socket 编程中 sockaddr 数据结构族的深入解析(以现代主流 Linux 内核版本为基准,基于 POSIX 标准和 glibc 实现)。sockaddr 族是 Socket API 的核心,用于表示网络地址、绑定端口和连接端点。它是抽象的地址结构,支持多种协议族(如 IPv4、IPv6、Unix Domain),确保 Socket 函数(如 bind、connect、accept)的通用性。
本文从基础概念、数据结构详解、代码示例、使用注意点到性能优化逐层展开。内容基于 Linux 内核源码整理,适用于实际开发。
1. sockaddr 族概述
- 核心作用:sockaddr 族用于存储 Socket 地址信息,包括协议族、IP 地址、端口等。Socket API(如 socket、bind、connect、sendto、recvfrom)统一使用
struct sockaddr *类型参数,实现协议无关性。 - 设计原则:C 语言的联合体(union)和填充(padding)设计,确保不同协议的地址结构大小一致,便于类型转换。
- 历史演进:
- POSIX.1-2001 标准化 sockaddr。
- Linux 内核 2.6+ 支持 IPv6(sockaddr_in6)。
- 现代优化:支持抽象命名空间(abstract namespace for Unix sockets,内核 2.6.27+),提升性能。
- 主流:兼容 eBPF Socket 过滤和 io_uring 异步 I/O,但 sockaddr 结构不变。
关键头文件:
#include<sys/socket.h>// sockaddr, sockaddr_storage
#include<netinet/in.h>// sockaddr_in, sockaddr_in6
#include<sys/un.h>// sockaddr_un
2. sockaddr 数据结构族详解
sockaddr 族是一个'家族',核心是 struct sockaddr,其他结构通过类型转换兼容它。所有结构以 sa_family 开头,确保协议族区分。
2.1 通用结构:struct sockaddr
- 大小:16 字节(sizeof(sockaddr) == 16)。
- 作用:作为 Socket 函数的通用参数。实际使用时,需强制转换为具体类型(如 (struct sockaddr *)&addr_in)。
- 注意:sa_data 是 opaque(不透明)的,不要直接访问。大小限制了其扩展性(故有 sockaddr_storage)。
定义(/usr/include/bits/socket.h):
struct sockaddr {
sa_family_t sa_family; // 地址族(如 AF_INET、AF_INET6、AF_UNIX)
sa_data[];
};

