好记性不如铅笔头

linux, 操作系统

【转】Linux网络编程 — socketpair的使用

本文转自【 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产生的套接字对实现全双工通信)

发表评论

15 + 10 =

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据