一、无名域套接字的创建(socketpair)
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>

int socketpair(int domain, int type, int protocol, int sockfd[2])
  • 功能:socketpair用来创建一对无命名的、相互连接的域套接字
  • 这种域套接字也可以看作是一种管道

参数:

  • domain:设置为AF_LOCAL或AF_UNIX
  • type:可以是SOCK_STREAM(流管道),也可以是SOCK_DGRAM(数据报管道)
  • protocol:必须设置为0
  • sockfd[2]:调用者需要自己创建一个数组,并且传入此参数中。若socketpair函数成功返回,sockfd数组保存着创建的域套接字描述符,这对套接字是成对使用的

域套接字的特点:

APUE编程:132---进程间通信(无名域套接字:socketpair)_数据

  • 一对相互连接的域套接字起到全双工管道的作用:两端对读和写开放
  • 与pipe创建的不同,pipe创建的是半双工的管道,只能一端读或一端写。而socketpair函数创建返回的是全双工的

两个套接字是如何进行读写的:

  • fd[0]的输入是fd[1]的输出
  • fd[0]的输出是fd[1]的输入
  • fd[1]的输入是fd[0]的输出
  • fd[1]的输出是fd[0]的输入

注意事项:

  • socketpair函数仅适用于域套接字,不能用于其他其他域
二、演示案例
  • 创建域套接字数组,父进程向fd[0]中写入数据,子进程从fd[1]中读取数据
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h
#include <errno.h>
#include <string.h>


int main(int argc,char argv[])
{
    int fd[2];
    pid_t pid;

    if(socketpair(AF_UNIX,SOCK_DGRAM,0,fd)==-1){ //创建域套接字
        perror("socketpair");
        exit(EXIT_FAILURE);
    }

    if((pid=fork())>0){  //父进程输入数据
        char buff[1024];
        printf("Enter:");
        fflush(stdout);

        scanf("%s",buff);
        if(write(fd[0],buff,strlen(buff))==-1){  //向fd[0]中写入数据,会被fd[1]读取
            perror("write");
            exit(EXIT_FAILURE);
        }
    }else if(pid==0){
        char buff[1024];
        if(read(fd[1],buff,sizeof(buff))==-1){  //从fd[1]读取数据,数据来自于fd[0]
            perror("read");
            exit(EXIT_FAILURE);
        }

        printf("recv:%s\n",buff);
    }else{
        perror("fork");
        exit(EXIT_FAILURE);
    }
    return 0;
}

APUE编程:132---进程间通信(无名域套接字:socketpair)_无名域套接字(socketpair)_02