Unix IPC之pipe
pipe创建函数:
#include <unistd.h> /* Create a one-way communication channel (pipe). If successful, two file descriptors are stored in PIPEDES; bytes written on PIPEDES[1] can be read from PIPEDES[0]. Returns 0 if successful, -1 if not. */ int pipe (int __pipedes[2]);
下面是一个测试实例,有些未说明函数,如Pipe,是pipe的一个包裹函数,二者参数及用法一致,仅仅是在包裹函数中添加了出错信息。
void client(int, int); void server(int, int); int main(int argc, char **argv) { int pipe1[2], pipe2[2]; pid_t childpid; Pipe(pipe1); /* create two pipes */ Pipe(pipe2); if ( (childpid = Fork()) == 0) /* child */ { Close(pipe1[1]); Close(pipe2[0]); server(pipe1[0], pipe2[1]); // 子线程作为服务器端 exit(0); } /* 4parent */ Close(pipe1[0]); Close(pipe2[1]); client(pipe2[0], pipe1[1]); Waitpid(childpid, NULL, 0); /* wait for child to terminate */ exit(0); }
/** * 从客户端读取文件名,打开文件并将文件内容返回给客户端 * @param readfd 管道读描述符 * @param writefd 管道写描述符 */ void server(int readfd, int writefd) { int fd; ssize_t n; char buff[MAXLINE + 1]; /* 4read pathname from IPC channel */ if ( (n = Read(readfd, buff, MAXLINE)) == 0) err_quit("end-of-file while reading pathname"); buff[n] = '\0'; /* null terminate pathname */ if ( (fd = open(buff, O_RDONLY)) < 0) { /* 4error: must tell client */ // 打开失败则直接将错误信息写入管道 snprintf(buff + n, sizeof(buff) - n, ": can't open, %s\n", strerror(errno)); n = strlen(buff); Write(writefd, buff, n); } else { /* 4open succeeded: copy file to IPC channel */ while ( (n = Read(fd, buff, MAXLINE)) > 0) Write(writefd, buff, n); Close(fd); } } /** * 将键盘输入数据发送给服务器,并将服务器的回复信息显示在屏幕 * @param readfd 管道读描述符 * @param writefd 管道写描述符 */ void client(int readfd, int writefd) { size_t len; ssize_t n; char buff[MAXLINE]; /* 4read pathname */ Fgets(buff, MAXLINE, stdin); // 从键盘获取输入信息 len = strlen(buff); /* fgets() guarantees null byte at end */ if (buff[len - 1] == '\n') len--; /* delete newline from fgets() */ /* 4write pathname to IPC channel */ Write(writefd, buff, len); // 写入管道 /* 4read from IPC, write to standard output */ while ( (n = Read(readfd, buff, MAXLINE)) > 0) Write(STDOUT_FILENO, buff, n); }
以上测试实例实现了一个如下的客户-服务器: