当前位置: 首页 > news >正文

socketpair函数详解

socketpair() 是 Unix/Linux 系统中用于创建一对相互连接的匿名套接字的系统调用,专为 进程间通信 (IPC) 设计。这对套接字在创建后即处于连接状态,无需绑定地址或手动连接,特别适用于父子进程或线程间通信。


函数原型

#include <sys/types.h>
#include <sys/socket.h>int socketpair(int domain, int type, int protocol, int sv[2]);
参数说明
domain协议族:通常为 AF_UNIX(本地通信)或 AF_LOCAL(同义)
type套接字类型:SOCK_STREAM(流式)或 SOCK_DGRAM(数据报)
protocol协议:通常为 0(自动选择)
sv[2]用于存储两个套接字描述符的数组(输出参数)
返回值成功返回 0,失败返回 -1 并设置 errno

核心特性

  1. 匿名连接
    • 套接字对在创建时已自动连接,无需调用 bind(), listen(), accept(), connect()
  2. 双向通信
    • 两个套接字均可读写(全双工)。
  3. 高效 IPC
    • 数据在内核中直接传递,无需经过网络协议栈。
  4. 无文件路径
    • 与命名 Unix 套接字不同,不会在文件系统中创建节点。

使用场景

  1. 父子进程通信
    • 父进程创建套接字对 → fork() → 父子进程各关闭一端 → 通过剩余套接字通信。
  2. 线程间通信
    • 线程可直接通过套接字描述符交换数据。
  3. 替代管道 (pipe)
    • 提供双向通信能力(管道是单向的)。

使用步骤

  1. 调用 socketpair() 创建套接字对
  2. 根据场景关闭不需要的描述符
  3. 通过 read()/write()send()/recv() 通信
  4. 通信完成后关闭所有描述符

示例代码:父子进程通信

#include <sys/socket.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>int main() {int sv[2];  // 套接字对pid_t pid;char buf[128];// 1. 创建流式套接字对if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == -1) {perror("socketpair");exit(1);}// 2. 创建子进程pid = fork();if (pid < 0) {perror("fork");exit(1);}if (pid == 0) { // 子进程close(sv[0]);  // 关闭父进程端// 3. 向父进程发送消息const char *msg = "Hello from child";write(sv[1], msg, strlen(msg) + 1);// 4. 接收父进程回复read(sv[1], buf, sizeof(buf));printf("Child received: %s\n", buf);close(sv[1]);  // 关闭子进程端exit(0);} else { // 父进程close(sv[1]);  // 关闭子进程端// 3. 接收子进程消息read(sv[0], buf, sizeof(buf));printf("Parent received: %s\n", buf);// 4. 回复子进程const char *reply = "Hello from parent";write(sv[0], reply, strlen(reply) + 1);close(sv[0]);  // 关闭父进程端wait(NULL);    // 等待子进程退出}return 0;
}

关键参数详解

1. domain 协议族
  • AF_UNIX / AF_LOCAL
    本地通信(进程间通信),唯一推荐选项(其他如 AF_INET 通常不支持)。
2. type 套接字类型
类型特性
SOCK_STREAM可靠、双向、面向连接的字节流(类似 TCP),无消息边界
SOCK_DGRAM数据报服务(类似 UDP),保留消息边界(在 AF_UNIX 中仍可靠)
扩展标志
SOCK_NONBLOCK非阻塞模式(Linux 特有,如 SOCK_STREAM | SOCK_NONBLOCK
SOCK_CLOEXEC执行 exec 时关闭描述符(避免泄漏)
3. protocol
  • 固定为 0(系统自动选择协议)。

与管道的对比

特性socketpair()pipe()
通信方向双向(全双工)单向(半双工)
数据流类型流式/数据报字节流
描述符数量2 个(均可读写)2 个(一个读,一个写)
进程关系需继承描述符(通常用于父子进程)同左
控制能力支持非阻塞、信号驱动等高级选项功能有限

常见错误处理

if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == -1) {switch(errno) {case EMFILE:  // 进程描述符耗尽perror("Too many open files");break;case EAFNOSUPPORT: // 不支持的协议族perror("Unsupported address family");break;case EPROTONOSUPPORT: // 不支持的协议perror("Unsupported protocol");break;default:perror("socketpair");}exit(EXIT_FAILURE);
}

注意事项

  1. 描述符关闭
    • 通信双方需显式关闭未使用的描述符(避免资源泄漏)。
  2. 协议族限制
    • 可移植代码应仅使用 AF_UNIX(其他协议族如 AF_INET 可能不被支持)。
  3. 阻塞与非阻塞
    • 默认阻塞模式,可通过 fcntl(fd, F_SETFL, O_NONBLOCK)SOCK_NONBLOCK 标志设为非阻塞。
  4. 进程关系
    • 套接字对只能在有亲缘关系的进程间继承(或通过 sendmsg() 传递描述符)。

适用场景对比

场景推荐方法
父子进程双向通信socketpair()
无亲缘关系进程通信命名 Unix 套接字
简单单向数据流(如日志)pipe()
高性能 IPC(Linux 特有)eventfd()/signalfd()

socketpair() 是进程间双向通信的轻量级解决方案,结合了管道的易用性和套接字的灵活性,尤其适合需要在亲缘进程间高效传递数据的场景。

http://www.dtcms.com/a/302017.html

相关文章:

  • CHI - Transaction介绍 - 其他类型介绍
  • 图论(BFS)构造邻接表(运用队列实现搜索)
  • Java面试深度剖析:从JVM到云原生的技术演进
  • 10.若依的自定义注解 Log
  • 发布“悟能”具身智能平台,商汤让机器人像人一样和现实世界交互
  • GitLab 18.2 发布几十项与 DevSecOps 有关的功能,可升级体验【一】
  • RAGFlow系列(03):把知识库通过API方式共享给Dify等外部平台使用
  • WPS 将一个PPT里面的图片和文字导入到另一个PPT中
  • CSP-J 2022_第三题逻辑表达式
  • 面试官:详细说说Kafka rebalance 的策略以及具体过程
  • 中国计算机学会(CCF)推荐学术会议-B(数据库/数据挖掘/内容检索):WSDM 2026
  • Rust并发编程中的所有权挑战与解决方案:从实际项目看Clone策略的应用
  • vue3卡片垂直无限滚动
  • Android 中 TCP 协议的实战运用
  • 【JAVA安全-Fastjson系列】Fastjson 1.2.24 反序列化漏洞分析及测试环境构建【复习回顾】
  • 安宝特案例丨户外通信机房施工革新:AR+作业流技术破解行业难题
  • 安宝特案例丨AR+AI赋能轨道交通制造:破解人工装配难题的创新实践
  • AR技术赋能工业设备维护:效率与智能的飞跃
  • keeplived实例
  • 基于Verilog的神经网络加速器设计
  • 微信小程序点击输入框时,顶部导航栏被遮挡问题如何解决?
  • 数值计算 | 图解基于龙格库塔法的微分方程计算与连续系统离散化(附Python实现)
  • 软件测试开发转型经验分享与职业发展指南
  • 基于FPGA和DDS原理的任意波形发生器(含仿真)
  • 可配置的PWM外设模块
  • Java Collections工具类
  • RocketMQ入门实战详解
  • 【MySQL学习|黑马笔记|Day1】数据库概述,SQL|通用语法、SQL分类、DDL
  • 【数据标注】详解使用 Labelimg 进行数据标注的 Conda 环境搭建与操作流程
  • 【unitrix】 6.20 非零整数特质(non_zero.rs)