socketpair 是一个在 UNIX 系统上用于创建一对通信套接字的系统调用。它可以用于进程间通信(IPC,Inter-Process Communication),允许两个进程通过这对套接字进行双向的数据交换。
socketpair 函数的定义和作用
函数原型:
int socketpair(int domain, int type, int protocol, int sv[2]);
- domain:指定协议族,通常使用
PF_UNIX(也可以写作AF_UNIX)表示 UNIX 域协议,用于本地进程间通信。 - type:指定套接字类型,通常使用
SOCK_STREAM(用于流式套接字)或SOCK_DGRAM(用于数据报套接字)。 - protocol:指定协议,通常为 0,表示使用默认协议。
- sv[2]:是一个包含两个整型值的数组,用于返回创建的两个套接字的文件描述符。这两个文件描述符代表这对连接的套接字,两个文件描述符可以在两个进程之间进行通信。
socketpair 的工作原理
socketpair 创建一对已连接的套接字,这对套接字的文件描述符 sv[0] 和 sv[1] 可以分别在两个进程之间传递,用于双向通信。
- 当一个进程向
sv[0]发送数据时,另一个进程可以通过sv[1]接收数据,反之亦然。 - 这种通信方式适用于同一台机器上的进程之间,无需使用网络协议栈。通常,它被用于同一台主机上的父进程与子进程之间的通信,或者在多进程应用程序中用于不同进程之间的消息传递。
返回值
- 成功:如果
socketpair成功创建了套接字,返回 0,并且sv数组将包含两个套接字的文件描述符。 - 失败:如果创建失败,返回 -1,并设置
errno以指示错误原因。
示例代码
下面是一个简单的使用 socketpair 创建通信套接字的例子:
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
int main() {
int sv[2]; // 用于存放套接字文件描述符
char buf[100];
pid_t pid;
// 创建一对连接的套接字
if (socketpair(PF_UNIX, SOCK_STREAM, 0, sv) == -1) {
perror("socketpair");
return 1;
}
pid = fork();
if (pid == -1) {
perror("fork");
return 1;
}
if (pid == 0) { // 子进程
close(sv[0]); // 关闭子进程中不需要的文件描述符
write(sv[1], "Hello from child", 16); // 向父进程发送数据
} else { // 父进程
close(sv[1]); // 关闭父进程中不需要的文件描述符
read(sv[0], buf, sizeof(buf)); // 从子进程读取数据
printf("Received from child: %s\n", buf);
}
return 0;
}
解释
socketpair(PF_UNIX, SOCK_STREAM, 0, sv)创建一对连接的 UNIX 域套接字,sv[0]和sv[1]用于父子进程间的通信。- 父进程通过
fork创建一个子进程。 - 父进程关闭
sv[1](不使用),子进程关闭sv[0](不使用),然后使用write和read进行数据交换。
总结
socketpair 是一个非常有用的系统调用,特别适用于进程间通信(IPC)。它通过创建一对双向的通信套接字,使得两个进程可以在同一台机器上进行高效、低延迟的数据交换,常用于父子进程之间的通信。