socketpair()函数会创建两个socket对象,其文件描述符保存在其第四个参数fds[2]数组中。通信时,父子进程中,其中一进程读写fds[0],另一进程读写fds[1],一进程从fds[0]写,另一进程从fds[1]中读出。反之亦然。
读写fds[]的阻塞问题:
1、当还没有往fds[1]写数据,尝试从fds[0]读数据时,将阻塞读。
2、当往fds[1]写了数据后,并且还没有从fds[0]端把数据读走,此时再次尝试往fds[1]写数据,则阻塞写。
socketpair()函数声明:
extern int socketpair(int __domain,int __type,int __protocol,int __fds[2])__THROW;
参数:
1、domain:指明socket对象所使用的地址簇或协议簇。
2、type:socket类型
3、protocol:写为0即可。
4、fds[2]:保存socketpair()函数创建的两个socket对象的描述符。
使用示例:
int sock[2];
socketpair(PF_UNIX,SOCK_STREAM,0,sock);
完整例子:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
int main(int argc,char *argv[])
{
int sock[2];
int pid;
int i;
static char buf[128];
static char buf_read_to[128];
static char buf2[128];
static char buf_read_to2[128];
if(socketpair(PF_UNIX,SOCK_STREAM,0,sock) < 0) //创建socketpair对象,本地数据流
{
perror("socketpair");
exit(EXIT_FAILURE);
}
if((pid = fork()) == -1)
{
perror("fork");
exit(EXIT_FAILURE);
}
else if(pid == 0)//子进程
{
close(sock[1]);
for(i=0;i<10;i=i+2)
{
sleep(1);
sprintf(buf,"child,%d",i);
write(sock[0],buf,sizeof(buf));
read(sock[0],buf_read_to,sizeof(buf));
printf("child receive data from parent %s\n",buf_read_to);
}
close(sock[0]);
exit(EXIT_SUCCESS);
}
else
{
sleep(1);
close(sock[0]);
for(i=1;i<10;i=i+2)
{
read(sock[1],buf_read_to2,sizeof(buf_read_to2));
printf("parent receive data from child %s\n",buf_read_to2);
sprintf(buf2,"parent,%d",i);
write(sock[1],buf2,sizeof(buf2));
}
close(sock[1]);
exit(EXIT_SUCCESS);
}
return 0;
}