本文转自【 http://blog.csdn.net/y396397735/article/details/50684558 】
Linux实现了一个源自BSD的socketpair调用,可以实现在同一个文件描述符中进行读写的功能。
该系统调用能创建一对已连接的UNIX族socket。
在Linux中,完全可以把这一对socket当成pipe返回的文件描述符一样使用,唯一的区别就是这一对文件描述符中的任何一个都可读和可写,函数原型如下:
#include <sys/types.h> #include <sys/socket.h> int socketpair(int domain, int type, int protocol, int sv[2]);
socketpair()函数建立一对匿名的已经连接的套接字,其特性由协议族d、类型type、协议protocol决定,建立的两个套接字描述符会放在sv[0]和sv[1]中。
socketpair函数参数说明:
第1个参数domain,表示协议族,只能为AF_LOCAL或者AF_UNIX。
第2个参数type,表示协议,可以是SOCK_STREAM或者SOCK_DGRAM。用SOCK_STREAM建立的套接字对是管道流,与一般的管道相区别的是,套接字对建立的通道是双向的,即每一端都可以进行读写。
第3个参数protocol,表示类型,只能为0。
第4个参数sv[2]是接收代表两个套接口的整数数组。每一个文件描述符代表一个套接口,并且与另一个并没有区别。
函数返回值:
如果函数成功,将会返回0值。否则将会返回-1表明创建失败,并且errno来表明特定的错误号。
以下给出个简单的例子,通过socketpair实现父子间进程通信:
/*socketpair1.c*/ #include <sys/types.h> #include <sys/socket.h> #include <stdlib.h> #include <stdio.h> int main () { int fd[2]; int r = socketpair(AF_UNIX, SOCK_STREAM, 0, fd); if (r < 0){ perror( "socketpair()" ); exit(1); } if (fork()){ /* 父进程 */ int val = 0; close(fd[1]); while (1){ sleep(1); ++val; printf("发送数据: %d\n", val); write(fd[0], &val, sizeof(val)); read(fd[0], &val, sizeof(val)); printf("接收数据: %d\n", val); } }else{ /*子进程*/ int val; close(fd[0]); while(1){ read(fd[1], &val, sizeof(val)); ++val; write(fd[1], &val, sizeof(val)); } } }
yu@ubuntu:~/Linux/217/pro_pool/socketpair$ vi socketpair1.c yu@ubuntu:~/Linux/217/pro_pool/socketpair$ gcc -o socketpair1 socketpair1.c yu@ubuntu:~/Linux/217/pro_pool/socketpair$ ./socketpair1 发送数据: 1 接收数据: 2 发送数据: 3 接收数据: 4 发送数据: 5 接收数据: 6 ...
分析程序:一开始由socketpair创建一个套接字对,父进程关闭fd[1],子进程关闭fd[0],父进程sleep(1)让子进程先执行,子进程read(fd[1], &val, sizeof(val))阻塞,然后父进程write(fd[0]..)发送数据,子进程接收数据处理后再发送给父进程数据write(fd[1]..),父进程读取数据,打印输出。(注意:socketpair产生的套接字对实现全双工通信)
发表评论