socketpair和dup---高级I/O

来源:互联网 发布:CCD软件接口GiGe 编辑:程序博客网 时间:2024/06/04 19:43

一、我们在学习进程间通信的时候学习过匿名管道pipe,匿名管道的特点:

  • 只能用于单向通信
  • 只能用于有血缘关系的两个进程,通常是父子进程
  • 生命周期随进程
  • 面向字节流
  • 具有同步机制

我们现在学习一种新的管道socketpair,可以用于双向通信,也是用于父子进程,代码实现与匿名管道类似

#include<stdio.h>#include<sys/types.h>#include<sys/socket.h>#include<string.h>#include<stdlib.h>#include<unistd.h>int main(){    int fd[2];//fd[0]文件描述符读端  fd[1]文件描述符写端    //创建管道    if(socketpair(AF_LOCAL,SOCK_STREAM,0,fd)<0){        perror("socketpair");        return 1;    }    //创建子进程    pid_t id = fork();    if(id<0){        perror("fork");        exit(2);    }else if(id == 0){//child-->first write next read        close(fd[0]);        char buf[1024];        memset(buf,0,sizeof(buf));        //子进程先向文件写数据,再从文件读数据        while(1){            ssize_t s = read(0,buf,sizeof(buf)-1);            if(s<0){                perror("read");                exit(3);            }            write(fd[1],buf,strlen(buf));            sleep(1);            s = read(fd[1],buf,sizeof(buf)-1);            buf[s] = '\0';            printf("child: Father say:%s",buf);        }    //父进程从文件读数据,再写入数据    }else{//father-->first read next write        close(fd[1]);        char msg[1024];        memset(msg,0,sizeof(msg));        while(1){            ssize_t r = read(fd[0],msg,sizeof(msg)-1);            if(r<0){                perror("read");                exit(4);            }            msg[r] = '\0';            printf("Father:Child say: %s",msg);            read(0,msg,sizeof(msg)-1);            write(fd[0],msg,strlen(msg));        }    }    return 0;}

结果图:
这里写图片描述

二、 dup对文件描述符重定向
1.我们之前学习新建文件的文件描述符是pcb中文件描述符表中未被使用的最小的一个文件描述符(默认打开0、1、2),方法如下:
这里写图片描述

先关闭我们想要使用的文件描述符0或1,在用open创建文件,此时fifo文件的fd即为0或1
这里写图片描述

2.如果我们首先创建文件,再想改变文件的fd ,这时就要用dup,文件描述符重定向;
这里写图片描述

先创建文件fifo,在关闭文件描述符,在dup
这里写图片描述

如果我们关闭的文件描述符是1(标准输出),且将fifo的文件描述符重定向为1,那么所有向标准输出上打印的东西全部输入到fifo文件中。