管道是無名的,只能用於有血緣關係之間的進程通訊。FIFO正是爲了彌補這個缺陷而設計出來的。服務器
#include <unistd.h>設計
int pipe(int fd[2]);code
經過宏S_ISFIFO來肯定一個描述符或文件是不是FIFO,惟一參數是stat結構體的st_mode成員。server
下面一個例子:進程
父進程使用客戶端程序,經過標準輸入調用一個路徑名來,而後經過管道發送給子進程,子進程使用服務器程序,經過管道獲取這個路徑名,而後將這個文件內容經過管道再發送給客戶端。客戶端再將文件內容打印出來。ip
代碼:get
/*mainpipe.c*/ int main(int argc, char **argv) { int pipe1[2],pipe2[2]; pid_t childpid; pipe(pipe1);//創建兩個管道,管道1用於客戶端將路徑名發送給服務器端 pipe(pipe2);//管道2用於將服務器端輸出內容發送給客戶端 if ((childpid = fork()) == 0) {//子進程 close(pipe1[1]);//關閉寫,只讀管道1 close(pipe2[0]);//關閉讀,只寫管道2 server(pipe1[0], pipe2[1]);//從第一個參數讀,第二個參數寫 exit(0); } /*parent*/ close(pipe1[0]); close(pipe2[1]); client(pipe2[0], pipe1[1]);//從第一個參數讀,第二個參數寫 waitpid(childpid, NULL, 0); exit(0); } #include <stdio.h> #include <string.h> #include <unistd.h> #define MAXLINE 1000 /*從標準輸入讀取一個路徑名,將這個路徑名寫入一個管道里去 ,再另一個管道讀取服務器端發送過來的內容,而後顯示在 標準輸出裏。第一個參數是讀取通道,第二個參數是寫入通道*/ //client.c void client(int readfd, int writefd) { size_t len; ssize_t n; char buff[MAXLINE]; fgets(buff, MAXLINE, stdin);//從標準輸入獲取一行,以換行符結尾的 len = strlen(buff); if (buff[len-1] == '\n') len--;//去除最後一個換行符 write(writefd, buff, len);//寫入到第二個參數裏去 while( (n = read(readfd, buff, MAXLINE)) > 0)//從第一個參數讀取,若是, //在服務器端這個管道關閉了,這裏將會返回0 write(STDOUT_FILENO, buff, n); } #include <stdio.h> #include <unistd.h> #include <string.h> #include <error.h> #include <fcntl.h> #include <errno.h> #define MAXLINE 1000 /*這是個服務器程序,從第一個參數讀取路徑名,而後打開這個路徑名, 將這個路徑名文件內容輸入到第二個參數寫入通道去*/ //server.c void server(int readfd, int writefd) { int fd; ssize_t n; char buff[MAXLINE+1]; if ( (n = read(readfd, buff, MAXLINE)) == 0) //從第一個參數讀取路徑名 perror("end of file while reading pathname"); buff[n] = '\0';給路徑名加一個結尾 if ( (fd = open(buff,O_RDONLY)) < 0) {//打開路徑名 snprintf(buff + n, sizeof(buff) - n, ":can't 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); } }