Unix网络编程——管道(1)

#include<unistd.h>

int pipe(int fd[2]);

实际步骤:

  1. 创建管道(fd[0]和fd[1]);
  2. fork;
  3. 父进程关闭管道的读出端口(fd[0]);
  4. 子进程关闭管道的写入端口(fd[1])。

数据流向:

用户态中的父进程 ---> 内核中的管道 ---> 用户态中的子进程

 

编程实现单向管道(单双工):

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<errno.h>
#include<fcntl.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<string.h>

#define MAXSIZE 1024




int main(int argc, char **argv)
{
    int fd[2];
    pid_t childpid;
    int len;
    char buffer[MAXSIZE];

    if(pipe(fd)<0)//initialize pipe
    {
        perror("pipe()");
        exit(1);
    }

    childpid=fork();//fork a child process
    if(childpid<0)
    {
        perror("fork()");
        exit(1);
    }

    if(childpid==0)//child process
    {
        close(fd[1]);
        len=read(fd[0],buffer,MAXSIZE);
        puts(buffer);
        close(fd[0]);
        exit(0);
    }
    else//parent process
    {
        close(fd[0]);
        write(fd[1],"hello world",12);
        close(fd[1]);
        wait(NULL);
        exit(0);
    }
 }

全双工管道:

可以使用单个全双工管道实现双向通信.

Unix网络编程卷2中的程序形式,在默认提供半双工管道的Unix系统中会出错:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<errno.h>
#include<fcntl.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<string.h>

#define MAXSIZE 1024




int main(int argc, char **argv)
{
    int fd[2],n;
    char c;
    pid_t childpid;

    pipe(fd);
    if((childpid=fork())==0)//child process
    {
        sleep(3);
        if((n=read(fd[0],&c,1))!=1)
        {
            perror("read()");

        }
        printf("child read %c\n",c);
        write(fd[0],"c",1);
        exit(0);
    }

    //parent process
    write(fd[1],"p",1);
    if((n=read(fd[1],&c,1))!=1)
    {
        perror("read()");

    }
    printf("parent read %c\n",c);
    exit(0);
}


全双工管道的真正实现:由两个半双工管道实现,从fd[1]写入的数据只能从fd[0]中读出,从fd[0]中写入的数据也只能从fd[1]中读出。

popen和pclose函数:

#include<stdio.h>

FILE *popen(const char *command, const char *type);

int pclose(FILE *stream);

这两个函数应用于Linux执行shell命令的场景。

函数popen先执行fork,然后调用exec以执行command,并且返回一个要么指向子进程的stdout,要么指向stdin的文件指针:

若type是”r”,则文件指针是连接到子进程执行command命令的标准输出;

如果type是”w”,则文件指针连接到子进程执行command命令的标准输入。

转自:https://blog.csdn.net/qq_29344757/article/details/70925123的例子:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<errno.h>
#include<fcntl.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<string.h>

#define MAXSIZE 1024




int main(int argc, char **argv)
{
    FILE *fp1,*fp2;
    char buffer[MAXSIZE];
    int n;

    fp1=popen("cat /etc/group","r");
    fp2=popen("grep root","w");

    while((n=fread(buffer,1,sizeof(buffer),fp1))>0)
    {
        fwrite(buffer,1,n,fp2);
    }
    pclose(fp1);
    pclose(fp2);
}


猜你喜欢

转载自blog.csdn.net/s_hit/article/details/81191573