socketpair是一个在Unix系统上用于创建一对相互连接的套接字的系统调用,它允许两个进程通过这对套接字进行双向的数据交换。以下是对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]:是一个包含两个整型值的数组,用于返回创建的两个套接字的文件描述符。这两个文件描述符代表这对连接的套接字,两个文件描述符可以在两个进程之间进行通信。
三、返回值
- 如果函数成功,返回0。
- 如果函数失败,返回-1,并设置errno来表明特定的错误号。
四、工作原理
socketpair函数在内核中创建一对相关联的套接字,这些套接字既可以进行读取操作又可以进行写入操作。它们之间存在某种关联,使得一个进程向其中一个套接字发送数据时,另一个进程可以从另一个套接字中接收到这些数据。这种通信方式适用于同一台机器上的进程之间,无需使用网络协议栈。
五、应用场景
socketpair通常被用于同一台主机上的父进程与子进程之间的通信,或者在多进程应用程序中用于不同进程之间的消息传递。它使得两个进程可以在同一台机器上进行高效、低延迟的数据交换。
六、使用示例
以下是一个使用socketpair函数进行进程间通信的示例代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
int main() {
int sv[2];
if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == -1) {
perror("socketpair");
exit(1);
}
pid_t pid = fork();
if (pid == -1) {
perror("fork");
exit(1);
} else if (pid == 0) {
// 子进程
close(sv[0]); // 关闭子进程中的读取套接字
char *message = "Hello from child process!";
if (write(sv[1], message, strlen(message)) == -1) {
perror("write");
exit(1);
}
close(sv[1]); // 关闭子进程中的写入套接字
exit(0);
} else {
// 父进程
close(sv[1]); // 关闭父进程中的写入套接字
char buffer[1024];
if (read(sv[0], buffer, sizeof(buffer)) == -1) {
perror("read");
exit(1);
}
printf("Message from child process: %s\n", buffer);
close(sv[0]); // 关闭父进程中的读取套接字
exit(0);
}
}
在这个示例中,首先调用socketpair函数创建了一对套接字,然后通过fork函数创建了一个子进程。在子进程中,关闭了读取套接字,然后使用write函数向写入套接字写入数据。在父进程中,关闭了写入套接字,然后使用read函数从读取套接字中读取数据。
综上所述,socketpair是一个非常有用的系统调用,特别适用于进程间通信(IPC)。它通过创建一对双向的通信套接字,使得两个进程可以在同一台机器上进行高效、低延迟的数据交换。