zoukankan      html  css  js  c++  java
  • socketpair创建双向通信的管道(全双工通信)

    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 = "我是孩子
    ";
    	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] = '';
    		printf("孩子说 : %s
    ",buf);
    	    }
    	}
        }
        else   //父亲
        {
    	//close(sv[1]);//关闭写端口
    	close(sv[0]);//关闭写端口
    	const char* msg = "我是父亲
    ";
    	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] = '';
    		printf("父亲说 : %s
    ",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]中读取

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


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


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

    赐教!

    
    
  • 相关阅读:
    引用 Geoprocessing调用ArcToolBox工具使用总结
    MySQL权限改观何时生效
    Ubuntu下安装*.bin挨次
    创立初始的MySQL权限
    MySQL的日期和光阴范例
    MySQL存取节制, 阶段1:连接证明
    让Linux操作零碎可以Mount NTFS分区
    Citrix进级XenDesktop桌面虚拟化产物
    如何在两台MySQL数据库间完成同步
    MySQL的数字
  • 原文地址:https://www.cnblogs.com/melons/p/5791793.html
Copyright © 2011-2022 走看看