Linux 中的 socket() 系统调用

97 阅读3分钟

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_UNIXUNIX 域套接字,用于同一台主机上的进程间通信。
PF_CAN/AF_CAN控制器局域网(CAN),用于汽车网络通信或嵌入式系统通信。
PF_PACKET原始套接字(RAW socket),可直接处理底层数据包(OSI 第二层)。
PF_NETLINKNetlink 套接字,用于用户空间与内核空间通信(如获取网络配置或状态信息)。

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_RAWroot 权限)。
  • 常用于网络调试工具(如 pingtcpdump)。

3. 参数: protocol

指定使用的具体协议(与 domaintype 配合)。如果设为 0,则使用与 domaintype 匹配的默认协议。具体值依赖于协议族:

3.1 常用协议 (针对 AF_INETAF_INET6)

协议描述
IPPROTO_TCPTCP面向连接的可靠协议。
IPPROTO_UDPUDP面向无连接的高速数据报传输协议。
IPPROTO_ICMPICMP网络控制协议,用于发送网络错误或诊断消息(如 ping)。
IPPROTO_RAWRAW Protocol提供访问网络层数据包的能力。

3.2 针对 PF_CAN 的协议号

常见协议号由 include/uapi/linux/can.h 中定义:

协议号宏定义描述
1CAN_RAW原始 CAN 协议,发送和接收 CAN 帧。
2CAN_BCM基于广播管理器(Broadcast Manager)的 CAN 协议,用于周期性或定时消息处理。
3CAN_TP16CAN 传输协议,16位寻址。
4CAN_TP20CAN 传输协议,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 决定具体使用的协议,domaintype 会限制 protocol 的可选范围。例如:

    • AF_INETSOCK_DGRAM 必须搭配 IPPROTO_UDP0
    • PF_CAN 必须搭配 CAN_RAWCAN_BCM 等。