最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
Linux socket 跨进程传递描述符实现技术
时间:2026-07-12 08:53:51 编辑:袖梨 来源:一聚教程网
Linux中跨进程传递文件描述符需通过Unix域套接字的sendmsg/recvmsg发送SCM_RIGHTS控制消息,使接收方获得指向相同内核文件表项的新fd,共享打开状态;仅AF_UNIX套接字支持,须正确设置地址族、路径权限及cmsg结构,并严格验证收发两端fd有效性。
Linux 中跨进程传递文件描述符,核心是利用 Unix Domain Socket 配合 sendmsg/recvmsg 传递 SCM_RIGHTS 类型的控制消息。这不是传一个整数,而是让内核在接收进程中创建一个新的 fd,指向与发送方相同的内核文件表项——真正实现“共享打开状态”,包括偏移量、访问模式、锁等。
关键前提:必须用 Unix 域套接字
只有 AF_UNIX 类型的 socket(流式 SOCK_STREAM 或数据报 SOCK_DGRAM)支持描述符传递。TCP/IP 套接字不支持。常见错误是误用网络 socket 或未正确设置地址族。
- 服务端需 bind 到本地路径(如
/tmp/fdsock),并 listen/accept;客户端 connect 到该路径 - 父子进程间可直接用
socketpair(AF_UNIX, SOCK_STREAM, 0, sv)快速建立双向通道,省去 bind/connect 步骤 - 路径权限需合理(如 0700),避免非授权进程连接
发送端:构造带 SCM_RIGHTS 的控制消息
发送 fd 时,不能用普通 send,必须填充 msghdr 并附带 cmsg 控制数据。重点在 msg_control 字段的组织。
- 分配足够空间:用
CMSG_SPACE(sizeof(int))计算缓冲区大小,包含头部+数据 - 设置 cmsg 头部:
cmsg_level = SOL_SOCKET,cmsg_type = SCM_RIGHTS - 把待传 fd 写入
CMSG_DATA(cmsg),注意是 int 值,不是指针 -
msg_iov可只传 1 字节 dummy 数据(如 "x"),因为实际 payload 是控制消息,不是 iov
接收端:安全提取并验证 fd
recvmsg 后需遍历控制消息,确认类型和层级,并检查返回 fd 是否有效。忽略验证可能引发后续读写失败或资源泄漏。
- 调用
CMSG_FIRSTHDR(&msg)获取首个 cmsg 指针 - 校验
cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS - 用
CMSG_DATA(cmsg)取出 int 值,赋给新变量(如int newfd = *(int*)CMSG_DATA(cmsg)) - 立即检查
newfd >= 0,若为 -1 表示传递失败(如对方关闭 socket 或权限不足)
注意事项与典型陷阱
这套机制看似简单,但几个细节处理不当会导致静默失败或崩溃:
- 发送前确保目标 fd 已打开且未 close-on-exec(
fcntl(fd, F_SETFD, 0)清除 FD_CLOEXEC) - 接收后建议用
fstat(newfd, &st)验证是否可读/写,避免误用无效 fd - 多个 fd 可一次传递:把多个 int 放进同一块 CMSG_DATA 区域,长度设为
sizeof(int) * n - 不要在多线程中对同一 socket 并发 sendmsg/recvmsg,除非加锁或使用独立 socket 对
相关文章
- 街舞演出视频 07-22
- Mahadev 能量与恶魔的战争 07-22
- E站ehviewer网页版入口-ehviewer网页版进入口官网 07-22
- Valkyrie 动漫 战斗 Sakuga 07-22
- 巨鳄突袭购物中心 07-22
- 他山石:你喂AI越多知识,它反而越笨?三个结构性死结 07-22