ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

Unix网络编程-进程间通信---4、最初的Unix IPC -- 管道

2021-05-02 16:33:05  阅读:171  来源: 互联网

标签:--- int 间通信 read Unix fd 进程 客户端 buff


1、客户端服务器需求


2、int pipe(int fd[2])//返回两个文件描述符,fd[0]读,fd[1]写;

宏S_ISFIFO用来确定一个文件描述符或者文件是管道还是FIFO;

3、半双工通信管道的使用:

一对父子进程,由父进程创建一个管道,子进程复制副本;父进程关闭读fd[0],子进程关闭写fd[1];实现了单向父 ----> 子的通信
因为父进程创建的管道资源是属于父子进程公共分享的空间,这个资源只在父进程创建了一份;


4、如何理解who | sort | lp   ----->

实际上是终端bbsh创建了先创建了2个父进程管道空间和三个进程:

(1)piie()--->exec()

4、如何实现全双工通信

(1)父进程创建两个管道,一个管道用于读,一个用于写
子进程捏住读和写句柄;
父进程也同时捏住读和写;
对于用户态来说,只需要往自己拿着的句柄当作普通文件是使用即可;
比如说父进程客户端-》先发送文件路径过去,write(fd1, pathname, n); 然后等着读文件的内容:read(fd2, buff, n);
同理子进程作为服务器:先接收文件路径:read(fd1, buff_pathname, n); 然后打开这个文件,再把内容发送给客户端write(fd2. buffcontex, n);
 

int main()
{
int pipe1[2],pipe2[2];;

pipe(pipe1);
pipe(pipe2);
childpid = fork();
if(child == 0) // 子进程--->服务器
{
    close(pipe1[1]);//关1写---》pipe1[0]用于读
    close(pipe2[0]);//关2读---》pipe2[1]用于写

    server(pipe1[0], pipe2[1]);  
    exit(0);
}
//父进程---》客户端
close(pipe1[0]);
close(pipe2[1]);
client(pipe1[1], pipe2[0]);

//pid_t waitpid(pid_t pid, int *status, int options);
waitpid(childpid, NULL, 0);//
exit(0);
}
//子进程调用exit的时候,将变成僵尸进程,内核会给父进程发送SIGCHILD信号,父进程默认是忽略的,但是此处使用了waitpid取得终止子进程的终止状态;
//如果没有waitpid的话,一旦父进程终止后,这个子进程将变成孤儿进程(托孤给init进程管理),内核将为此向init进程发送另外一个SIGCHLD信号
 

 

void client(int readfd, int writefd) //客户端从标准输入获取文件路径, 发送到服务器,然后接收文件内容
{
    fgets(buff, MAXLINE, stdin);//fgets会把\n字符也算进去,这样len就等于实际字节数+1(\n)了;
    len = strlen(buff);

    if(buff[len-1] == '\n')//这个是成立的
        len=len-1;
    write(writefd, buff, len);

    while( (n = read(readfd, buff, len))  > 0)//给完路径就等着接收数据了
    {
        printf("%s\n", buff);
   }
}

 

void server(int readfd, int writefd)//服务器先接收客户端发来的文件路径,然后打开文件,把文件内容发送给客户端
{

    n = read(readfd, buff, MAXLINE);
    buff[n] = '\0';//注意不是buff[n-1]

    fd = open(buff, O_RDONLY);
    if(fd < 0)//打开出错了,告诉客户端发过来的路径有问题
    {
        snprintf(buff + n, sizeof(buff) - n; ":can't open %s\n", strerror(errno));
        write(writefd, buff, n);
    }
    else
    {
        while((n = read(fd, buff, MAXLINE)) > 0)
        {
            write(writefd, buff, n);
       }
        close(fd);
    }

}

 

5、Unix网络编程---进程间通信书中提到某些系统通过单管道实现全双工通信,实际上再很多系统上是不支持的

#include<unistd.h>
#include<stdio.h>
int main(void)
{
        int fd[2], n;
        char c;
        pid_t childpid;

        pipe(fd);
        childpid = fork();
        if(childpid == 0)
        {
                sleep(3);
                n = read(fd[0], &c, 1);
                printf("child read %c\n", c);
                write(fd[0], "c", 1);
                exit(0);
        }
        waitpid(childpid, NULL, 0);

        write(fd[1], "p", 1);
        n = read(fd[1], &c, 1);
        printf("parents read %c\n", c);

        return 0;
}

 

6、标准IO也提供了操作管道的接口(这一块用到的是再学吧,跟用户输入有关)

#include<stdio.h>
FILE * popen (const char* command, const char *type);//其中command是一个
int pclose(FILE* stream);
 

 

 

 

标签:---,int,间通信,read,Unix,fd,进程,客户端,buff
来源: https://blog.csdn.net/LuckyDog0623/article/details/116353102

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有