sockpair创建双向通信的管道

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));
		}
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_40822052/article/details/89765490