Linux下socketpair介绍:

socketpair创建了一对无名的套接字描述符(只能在AF_UNIX域中使用),描述符存储于一个二元数组,例如sv[2] .这对套接字可以进行双工通信,每一个描述符既可以读也可以写。这个在同一个进程中也可以进行通信,向sv[0]中写入,就可以从sv[1]中读取(只能从sv[1]中读取),也可以在sv[1]中写入,然后从sv[0]中读取;但是,若没有在0端写入,而从1端读取,则1端的读取操作会阻塞,即使在1端写入,也不能从1读取,仍然阻塞;

Linux实现了一个源自BSD的socketpair调用,可以实现在同一个文件描述符中进行读写的功能。该系统调用能创建一对已连接的UNIX族socket。在Linux中,完全可以把这一对socket当成pipe返回的文件描述符一样使用,唯一的区别就是这一对文件描述符中的任何一个都可读和可写,函数原型如下

<span style="font-size:18px;">int socketpair(int d, int type, int protocol, int sv[2]);</span>
参数介绍:

socketpair()函数建立一对匿名的已经连接的套接字,其特性由协议族d、类型type、协议protocol决定,建立的两个套接字描述符会放在sv[0]和sv[1]中。

第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]; //一对无名的套接字描述符
if(socketpair(PF_LOCAL,SOCK_STREAM,0,sv) < 0) //成功返回零 失败返回-1
{
perror("socketpair");
return 0;
} pid_t id = fork(); //fork出子进程
if(id == 0) //孩子
{
//close(sv[0]); //在子进程中关闭读
close(sv[1]); //在子进程中关闭读 const char* msg = "我是孩子\n";
char buf[1024];
while(1)
{
// write(sv[1],msg,strlen(msg));
write(sv[0],msg,strlen(msg));
sleep(1); //ssize_t _s = read(sv[1],buf,sizeof(buf)-1);
ssize_t _s = read(sv[0],buf,sizeof(buf)-1);
if(_s > 0)
{
buf[_s] = '\0';
printf("孩子说 : %s\n",buf);
}
}
}
else //父亲
{
//close(sv[1]);//关闭写端口
close(sv[0]);//关闭写端口
const char* msg = "我是父亲\n";
char buf[1024];
while(1)
{
//ssize_t _s = read(sv[0],buf,sizeof(buf)-1);
ssize_t _s = read(sv[1],buf,sizeof(buf)-1);
if(_s > 0)
{
buf[_s] = '\0';
printf("父亲说 : %s\n",buf);
sleep(1);
}
// write(sv[0],msg,strlen(msg));
write(sv[1],msg,strlen(msg));
}
}
return 0;
}
这里只是代码,整体流程,意思就是,父子进程间正在全双工通信,个人理解即就是同时通信。

代码中有两行一样,一行被注释掉了,这正是说明博文第一段中的话:

“向sv[0]中写入,就可以从sv[1]中读取(只能从sv[1]中读取),也可以在sv[1]中写入,然后从sv[0]中读取”

整个流程就是,子进程写父进程读和父进程写子进程读同时在进行:上一张图看看:



截取一段代码,两个红色线的方向,都是从一个进程的写到另一个进程的读,同时进行,看运行结果:



打印时,成对打印,双向通信!

赐教!


socketpair创建双向通信的管道(全双工通信)的更多相关文章

  1. linux下有名管道进程通信

    一.任务 1.学习mkfifo等函数: 2.了解有名管道的特点.阻塞打开与非阻塞打开等: 3.编写一个关于有名管道进程通信的程序,并运行. 二.相关概念 1.相关函数 创建有名管道的函数是mkfifo ...

  2. java socket实现全双工通信

    java socket实现全双工通信 单工.半双工和全双工的定义 如果在通信过程的任意时刻,信息只能由一方A传到另一方B,则称为单工. 如果在任意时刻,信息既可由A传到B,又能由B传A,但只能由一个方 ...

  3. wcf中的使用全双工通信

    wcf中的契约通信默认是请求恢复的方式,当客户端发出请求后,一直到服务端回复时,才可以继续执行下面的代码. 除了使用请求应答方式的通信外,还可以使用全双工.下面给出例子: 1.添加一个wcf类库 2. ...

  4. wcf中的使用全双工通信(转)

    wcf中的使用全双工通信   wcf中的契约通信默认是请求恢复的方式,当客户端发出请求后,一直到服务端回复时,才可以继续执行下面的代码. 除了使用请求应答方式的通信外,还可以使用全双工.下面给出例子: ...

  5. 使用 Visual Studio Team Services 和 IIS 创建持续集成管道

    若要将应用程序开发的生成.测试和部署阶段自动化,可以使用持续集成和部署 (CI/CD) 管道. 本教程介绍如何在 Azure 中使用 Visual Studio Team Services 和 Win ...

  6. WCF全双工通信实例分享(wsDualHttpBinding、netTcpBinding两种实现方式)

    最近在研究WCF通信,如果没有接触过的可以看我的前一篇文章:https://www.cnblogs.com/xiaomengshan/p/11159266.html 主要讲的最基础的basicHttp ...

  7. 根据Unix哲学来编写你的HTML5 Websocket服务器来实现全双工通信

    websocketd代表WebSocket的守护进程 websocketd处理的是浏览器和服务器之间的WebSocket连接,它会启动你所指定的服务器端应用来对WebSockets进行处理,然后在浏览 ...

  8. java线程间通信之通过管道进行通信

    管道流PipeStream是一种特殊的流,用于在不同线程间直接传送数据,而不需要借助临时文件之类的东西. jdk中提供了四个类来使线程间可以通信: 1)PipedInputStream和PipedOu ...

  9. Java使用PipedStream管道流通信

    多线程使用PipedStream 通讯 Java 提供了四个相关的管道流,我们可以使用其在多线程进行数据传递,其分别是 类名 作用 备注 PipedInputStream 字节管道输入流 字节流 Pi ...

随机推荐

  1. ajax面试题

    1.ajax是什么?如何创建一个ajax? ajax并不算是一种新的技术,全称是asynchronous javasript and xml,可以说是已有技术的组合,主要用来实现客户端服务器的异步通信 ...

  2. $PkuWc\ 2018$ 酱油记

    PkuWc 2018 酱油记 1. Day -INF 又停了一个月课...... 感觉这个月的收获还是蛮大的,刚来的时候还只会线段树,到现在LCT都学了... 这个月不停在考试,自己考试技巧也提升了不 ...

  3. 【Luogu1291】百事世界杯之旅(动态规划,数学期望)

    [Luogu1291]百事世界杯之旅(动态规划,数学期望) 题面 洛谷 题解 设\(f[i]\)表示已经集齐了\(i\)个名字的期望 现在有两种方法: 先说我自己的: \[f[i]=f[i-1]+1+ ...

  4. mailgun 发邮件示例代码Python版

    1 首先到mailgun官网注册账号,并激活账号 点击domains,进入默认的域名,最底下那个sandbox域名就是默认的测试域名 如果自己有域名,也可以添加自己的域名测试,具体参考:ssr pan ...

  5. 关于jstl的使用

    1.jsp中el表达式无法被解析 使用jstl标签的时候,发现el表达式无法被解析,后来查阅资料发现jsp中需要添加<%@page isELIgnored="false" % ...

  6. linux里所有命令都不存在

    打开/etc/profile ,看这个配置文件里的PATH变量,遍历这个变量里配置的多个路径,查看命令是否存在. 主要是这四个:/bin ,/usr/bin,/sbin,/usr/sbin. PATH ...

  7. WebService就是这么简单

    WebService介绍 首先我们来谈一下为什么需要学习webService这样的一个技术吧.... 问题一 如果我们的网站需要提供一个天气预报这样一个需求的话,那我们该怎么做????? 天气预报这么 ...

  8. Scala学习笔记(一)

    scala 版HelloWorrld object HelloWorld{ def main(args:Array[String]){ println("Hello World!!!&quo ...

  9. CMake基本语法

    CMake简介 CMake 是做什么的? CMake是一套类似于automake的跨平台辅助项目编译的工具. 我觉得语法更加简单易用. CMake的工作流程 CMake处理顶级目录的CMakeList ...

  10. Spring源码学习:第2步--使用SLF4j+Log4j日志框架替换掉其自身的commons-logging日志框架

    正如Spring官方文档所述,其底层的实现选择了commons-logging作为日志框架.这一"失足"性的选择,竟连Spring自身都抱怨.但是,谁叫Spring如此优秀呢,即使 ...