Linux 中的 socket() 系统调用用于创建套接字,其定义为:
int socket(int domain, int type, int protocol);
以下是各参数的详细解析:
1. 参数: domain
指定通信域(即协议族),定义了通信所使用的底层协议和地址格式。常见的 domain 值包括:
| 值 | 描述 |
|---|---|
PF_INET/AF_INET | 使用 IPv4 网络协议进行通信,例如 TCP 和 UDP。 |
PF_INET6/AF_INET6 | 使用 IPv6 网络协议。 |
PF_UNIX/AF_UNIX | UNIX 域套接字,用于同一台主机上的进程间通信。 |
PF_CAN/AF_CAN | 控制器局域网(CAN),用于汽车网络通信或嵌入式系统通信。 |
PF_PACKET | 原始套接字(RAW socket),可直接处理底层数据包(OSI 第二层)。 |
PF_NETLINK | Netlink 套接字,用于用户空间与内核空间通信(如获取网络配置或状态信息)。 |
PF_和AF_是历史原因的两组宏,数值相同,通常可互换。
2. 参数: type
指定套接字的类型,定义了通信行为或模式。例如,是否提供可靠通信、是否分段传输等。常见的 type 值包括:
| 值 | 描述 |
|---|---|
SOCK_STREAM | 面向连接的可靠字节流传输(TCP)。 |
SOCK_DGRAM | 面向无连接的数据报传输(UDP)。 |
SOCK_RAW | 直接处理网络层数据包(如 ICMP)。 |
SOCK_SEQPACKET | 类似 SOCK_STREAM,但对消息分段,保留分界(常见于本地通信如 AF_UNIX)。 |
SOCK_RDM | 可靠数据报消息(很少使用,Linux 未实现)。 |
2.1 SOCK_RAW 的特殊性
SOCK_RAW允许用户直接操作数据报的首部,例如 IP 首部、传输层首部等。- 需要更高的权限(如
CAP_NET_RAW或root权限)。 - 常用于网络调试工具(如
ping、tcpdump)。
3. 参数: protocol
指定使用的具体协议(与 domain 和 type 配合)。如果设为 0,则使用与 domain 和 type 匹配的默认协议。具体值依赖于协议族:
3.1 常用协议 (针对 AF_INET 和 AF_INET6)
| 值 | 协议 | 描述 |
|---|---|---|
IPPROTO_TCP | TCP | 面向连接的可靠协议。 |
IPPROTO_UDP | UDP | 面向无连接的高速数据报传输协议。 |
IPPROTO_ICMP | ICMP | 网络控制协议,用于发送网络错误或诊断消息(如 ping)。 |
IPPROTO_RAW | RAW Protocol | 提供访问网络层数据包的能力。 |
3.2 针对 PF_CAN 的协议号
常见协议号由 include/uapi/linux/can.h 中定义:
| 协议号 | 宏定义 | 描述 |
|---|---|---|
1 | CAN_RAW | 原始 CAN 协议,发送和接收 CAN 帧。 |
2 | CAN_BCM | 基于广播管理器(Broadcast Manager)的 CAN 协议,用于周期性或定时消息处理。 |
3 | CAN_TP16 | CAN 传输协议,16位寻址。 |
4 | CAN_TP20 | CAN 传输协议,20位寻址。 |
Note: 用户可以自行查看源码 (
include/uapi/linux/can.h) 获取完整列表。
4. 调用示例
以下示例展示不同参数组合的用途:
4.1 创建一个 TCP 套接字(IPv4)
c
CopyEdit
int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
// 或等效于
int sock = socket(AF_INET, SOCK_STREAM, 0);
4.2 创建一个原始套接字,用于发送 ICMP 数据包(如 ping 工具)
c
CopyEdit
int sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
4.3 创建一个 UDP 套接字(IPv6)
c
CopyEdit
int sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
4.4 创建一个 CAN 原始套接字
c
CopyEdit
int sock = socket(PF_CAN, SOCK_RAW, CAN_RAW);
4.5 创建一个 UNIX 域套接字用于本地通信
c
CopyEdit
int sock = socket(AF_UNIX, SOCK_SEQPACKET, 0);
5. 参数之间的关系
-
domain决定地址格式和协议族(如AF_INET对应 IPv4,AF_CAN对应 CAN)。 -
type决定通信特性(如流式或数据报)。 -
protocol决定具体使用的协议,domain和type会限制protocol的可选范围。例如:AF_INET与SOCK_DGRAM必须搭配IPPROTO_UDP或0。PF_CAN必须搭配CAN_RAW、CAN_BCM等。