socketpair

int socketpair(int domain, int type, int protocol, int sockfd[2]); //创建未命名的全双工管道

domain只能为AF_UNIX,也就是限制在本地使用

type可以是SOCK_STREAM或SOCK_DGRAM,SOCK_STREAM相当于创建了双向流管道,管道的每一端都可以write或read,并且两端的数据流对流是分开的

protocol必须是0

sockfd数组返回管道两端的socket描述符

在2.6.27的内核版本后,type支持了SOCK_CLOEXEC(close on exec )和SOCK_NONBLOCK(非阻塞系统描述符)标志,以节省fcntl系统调用

socketpair创建的描述符常用于亲缘进程间通信,如父进程调用了socketpair后,父进程再调用fork出子进程,子进程自动继承了描述符(前提是没有close on exec),那么父子进程就可以用sockfd进行通信。

例子,父进程在sockepair后,再fork出子进程,然后:

#include<sys/types.h>
#include<sys/wait.h>
#include<sys/socket.h>
#include<unistd.h>
#include<iostream>
#include<cstring>
using namespace std;
int main(){
    int fd[2];
    if(socketpair(AF_UNIX,SOCK_STREAM,0,fd)<0)//父进程调用socketpair创建fd数组
        cout<<"socketpair error"<<endl;
    pid_t pid;
    if((pid=fork())<0)
        cout<<"fork error"<<endl;
    else if(pid==0){
        close(fd[0]);//父进程持有fd[0]端,子进程持有fd[1]端
        write(fd[1],"hello parent",strlen("hello parent"));//子进程通过fd[1]向父进程发送消息

        char buf[20];
        while(read(fd[1],buf,20)==-1);//子进程在fd[1]端等待父进程的消息
        buf[13]=‘\0‘;
        cout<<"child receive: "<<buf<<endl;
    }
    else{
        close(fd[1]);
        write(fd[0],"hello child",strlen("hello world"));//父进程通过fd[0]端向子进程发送消息

        char buf[20];
        while(read(fd[0],buf,20)==-1);//父进程在fd[0]端等待子进程的消息
        cout<<"parent receive: "<<buf<<endl;
        wait(NULL);
    }
    return 0;
}

程序输出:

parent receive: hello parent

child receive: hello child

可见socketpair创建的UNIX域套接字可用于亲缘进程间通信(未命名限制了只能在亲缘进程间使用),在nginx中,master进程就利用socketpair创建套接字然后fork出worker进程,这样master进程和worker进程间就可以利用socketpair产生的套接字通信了。

socketpair

时间: 2024-10-11 23:00:58

socketpair的相关文章

socketpair的使用

socketpair函数概要例如以下:#include <sys/types.h>#include <sys/socket.h>int socketpair(int domain, int type, int protocol, int sv[2]);sys/types.h文件须要用来定义一些C宏常量.sys/socket.h文件必须包括进来定义socketpair函数原型.socketpair函数须要四个參数.他们是:套接口的域套接口类型使用的协议指向存储文件描写叙述符的指针 类

Libevent学习之SocketPair实现

Libevent设计的精化之一在于把Timer事件.Signal事件和IO事件统一集成在一个Reactor中,以统一的方式去处理这三种不同的事件,更确切的说是把Timer事件和Signal事件融合到了IO多路复用机制中. Timer事件的融合相对清晰简单,其套用了Reactor和Proactor模式(如Windows上的IOCP)中处理Timer事件的经典方法,其实Libevent就是一个Reactor嘛.由于IO复用机制(如Linux下的select.epoll)允许使用一个最大等待时间(即最

socketpair和pipe的区别

http://blog.csdn.net/bingqingsuimeng/article/details/9055499 管道pipe是半双工的,pipe两次才能实现全双工,使得代码复杂.socketpair直接就可以实现全双工. socketpair对两个文件描述符中的任何一个都可读和可写,而pipe是一个读,一个写.

socketpair双方管道

使用pipe只能对有血缘关系的单向管道进行通信.不过,Linux实现了一个源自BSD的socketpair调用 (3),可以实现上述在同一个文件描述符中进行读写的功能(该调用目前也是POSIX规范的一部分 (4)).该系统调用能创建一对已连接的(UNIX族)无名socket.在Linux中,完全可以把这一对socket当成pipe返回的文件描述符一样使用,唯一的区别就是这一对文件描述符中的任何一个都可读和可写. 这似乎可以是一个用来实现进程间通信管道的好方法.不过,要注意的是,为了解决我前面的提

socketpair实现进程通信

pipe用来创建管道,但是单个管道只能单向通信,一端用于读,而另一端用于写.如果要实现进程双向通信,必须创建一对管道.具体实现忽略.而socketpair则可以用来创建双向通信的管道.取决于底层实现,打开的还是一个文件,fd[0],fd[1],管道中f[0]读端,f[1]写端. #include <sys/types.h> #include <sys/socket.h> int socketpair(int domain, int type, int protocol, int s

socketpair函数详解

我们先来看看socketpair函数的原型如下: int socketpair(int domain,int type,int protocol,int sv[]) 第一个参数表示协议族,必须为AF_LOCAL; 第二个参数表示类型,既可以是SOCK_STREAM,又可以是SOCK_DGRAM,当参数指定为SOCK_STREAM时,得到的结果称为流管道,它与一般管道的区别是留管道是全双工的,即两个描述符即可读有可写; 第三个参数只能为0: 第四个参数用于保存创建的套接字对: socketpair

高级IO中socketpair实现进程间通信以及重定向

sockpair实现进程间通信 我们以前学习的利用管道(此处为匿名管道)实现进程间通信,只能是单向的,一边只能读而另一边只能写,且只能在有血缘关系的进程间才能通信,若想实现双向通信就必须创建双向管道,而sockpair它的实现就是双向管道进行通信.它可以用来创建双向通信管道 1 #include<stdio.h>   2 #include<unistd.h>   3 #include<string.h>   4 #include<sys/types.h>  

[转] IPC之管道、FIFO、socketpair

管道和FIFO作为最初的UNIX IPC形式,现在已用得较少.SocketPair可作为全双工版本的管道,较为常用,这里简单做个笔记 管道 * 只用于有亲缘关系的进程间通信 * 单向,即半双工 (双向方法:1 使用2个管道 2 使用SocketPair) * pipe() => write()/read() FIFO (有名管道) * 可用于无亲缘关系的进程间通信 * 单向 * mkfifo() => open() => write()/read() SocketPair * 套接字(一

linux:利用socketpair来在进程间传递描述符

1.socketpair 2.sendmsg/recvmsg 3.UNIX域套接字传递描述字 功能:创建一个圈双工的流管道 原型: int socketpair(int domain, int type, int protocol, int sv[2]); 参数 domain :协议家族    type: 套接字种类    protocol:协议种类    sv:返回的套接字对 返回值: 成功返回0, 失败返回-1 通过sockpair创建的全双通管道可以实现父子间进程通讯 #include <