Linux下的sockpair:
sockpair创建了一对无名的套接字文件描述符,描述符存储了一个二元数组,例如sv[2],这对套接字可以双工通信。即每一端可以写没一端也可以可以读。这个在同一个进程中也是可以进行通信的,向sv[0]中写入,就可以从sv[1]中读取(只能从sv[1]中读取);也可以在sv[1]中写入,然后从sv[0]中读取;但是,若没有在0端写入,而从1端读取,则1端的读取操作会阻塞,即使在1端写入,也不能从1读取,仍然阻塞。
Linux实现了一个源自BSD的sockpair调用,可以实现在同一个文件描述符中进行读写的功能。该系统调用能创建一对已连接的UNIX族socket。在Linux中,完全可以把这一对socket当成pipe返回的文件描述符一样使用,唯一的区别就是这样一对文件描述符中的任何一个都可读和可写,函数原型:
int sockpair(int d,int type,int protocol,int sv[2]);
第1个参数d,表示协议族,只能为AF_LOCAL或者AF_UNIX;
第2个参数type,表示类型,只能为0。
第3个参数protocol,表示协议,可以是SOCK_STREAM或者SOCK_DGRAM。用SOCK_STREAM建立的套接字对是管道流,与一般的管道相区别的是,套接字对建立的通道是双向的,即每一端都可以进行读写。参数sv,用于保存建立的套接字对。
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
int main()
{
int sv[2];
int res = socketpair(PF_LOCAL,SOCK_STREAM,0,sv);
if(res<0)
{
perror("sockpair");
return 0;
}
pid_t pid = fork();
if(pid == 0)
{
close(sv[1]);
const char *msg = "I am child";
char buff[128] ;
while(1)
{
write(sv[0],msg,strlen(msg));
sleep(1);
int n = read(sv[0],buff,sizeof(buff)-1);
if(n>0)
{
buff[n] = '\0';
printf("child:%s\n",buff);
}
}
}
else
{
close(sv[0]);
const char *msg = "I am father";
char buff[128];
while(1)
{
int n=read(sv[1],buff,sizeof(buff)-1);
if(n>0)
{
buff[n] = '\0';
printf("father:%s\n",buff);
sleep(1);
}
write(sv[1],msg,strlen(msg));
}
}
}