PIPE目录
1. client与server通信2. 图解3. client和server进程通信简单代码实现lient.cserver.c1. client与server通信
client和server进程之间如何通信举个简单例子:
client端标准输入standard input,读进一个路径到buffer中,并把路径写入管道服务器从管道中读取这个路径到buffer中进行read操作: read成功,写入管道返回给clientread失败,也要回应client错误信息 client从管道中stdout到buffer来显示内容
管道由pipe函数创建,并提供一个单向数据流,管道一般是两个不同进程间的通信,父进程和子进程(只能是亲缘关系之间),先由一个父进程创建一个管道,再调用fork函数派生
2. 图解
画个图举个例子:
上述有两个管道pipe1和pipe2,半双工单向,往一个方向的数据流,需要一来一回就是创建两个pipe,双向数据流。
这里的client为父,server是派生出来的子
int pipe(int fd[2]); //ret 0 indicates success, else ret -1
fd[0] 用做写入信息到管道
fd[1] 用做读取管道信息
步骤如下:
创建pipe1和pipe2 , pipe1 fd[0]负责读,fd[1]负责写,pipe2 fd同理fork进行派生父进程关闭从pipe1读出端fd1[0]父进程关闭从pipe2写入端fd2[1]子进程关闭从pipe1写入端fd1[1]子进程关闭从pipe2读出端fd2[0]
WARNING:两个管道连接着两个进程,client和server在进行读出和写入的过程都穿越了内核
3. client和server进程通信简单代码实现
main.c
#include <stdio.h>#include "unpipc.h"void client(int,int), server(int,int);int main(int argc, char** argv){//pipe1 includes fd1[0], fd1[1]//pipe2 includes fd2[0], fd2[1]int pipe1[2], pipe2[2];pid_t childpid;//创建两个pipepipe(pipe1);pipe(pipe2);//判断是否childif( (childpid = fork())==0 ){/*关闭子进程中的 管道1的写入,关闭管道2的读出*/close(pipe1[1]);close(pipe2[0]);//调用server function,server端 传入管道1的读出,管道2的写入server(pipe1[0], pipe2[1]);exit(0);}/*关闭父进程中的 管道1的读出, 关闭管道2的写入*/close(pipe1[0]);close(pipe2[1]);//调用client function,client端 传入管道2的读出,管道1的写入client(pipe2[0], pipe1[1]);//等待child进程waitpid(childpid, NULL, 0);exit(0);}}
client.c
void client(int readfd, int writefd){size_t len;ssize_t n;char buff[MAXLINE];//获取标准输入到bufferfgets(buff, MAXLINE, stdin);len = strlen(buff);if(buff[len-1] == '\n' ) /*去掉回车符*/len--;//将buff info写入到管道write(writefd, buff, len);//读取buffer中的信息并标准输出while( (n = read(readfd, buff, MAXLINE)) >0 ){write(STDOUT_FILENO, buff, n);}
server.c
void server(int readfd, int writefd){int fd;ssize_t n;char buff[MAXLINE+1];//从管道中读取info到bufferif( (n=read(readfd, buff, MAXLINE)) == 0)printf("end of file while reading pathname");buff[n] = '\0';//进行打开读取操作,成功则写入到buffer,否则把错误信息写入到管道if((fd = open(buff, O_RDONLY)) < 0 ){snprintf(buff+n, sizeof(buff)-n, ": cant open, %s \n", strerror(errno) );n = strlen(buff);write(writefd, buff, n);}else{while((n = read(fd, buff, MAXLINE))>0 )write(writefd, buff, n);close(fd);}}
如果对你有帮助,一键三连 All the best plus thank you~ 😃