例子:服務器只經過SERV_FIFO文件獲取各個客戶端發過來的文件路徑名以及與此客戶端通訊的fifo文件名(由/tmp/fifo.pid組成,這裏所須要的就是客戶端的pid號)。服務器把文件打開後,將文件內容輸入與此客戶端通訊的fifo,最後客戶端今後fifo獲取文件內容,而後輸出到標準輸出。服務器
代碼:code
//mainserver.c #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <string.h> #include <errno.h> #define MAXLINE 1000 #define FILEMODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP) #define SERV_FIFO "/tmp/serv_fifo"//服務器永遠都只今後fifo文件獲取信息 int main(int argc, char **argv) { int readfifo, writefifo, dummyfd, fd; char *ptr, buff[MAXLINE+1],fifoname[MAXLINE], bufferror[20]; pid_t pid; ssize_t n; if ((mkfifo(SERV_FIFO, FILEMODE) < 0) && (errno != EEXIST)) { snprintf(bufferror, sizeof(bufferror), "can't create %s\n", SERV_FIFO); perror(bufferror); } readfifo = open(SERV_FIFO, O_RDONLY, 0);//以只讀模式打開服務器FIFO dummyfd = open(SERV_FIFO, O_WRONLY, 0);//這種寫模式打開,永遠用不到 while ((n = read(readfifo, buff, MAXLINE)) > 0) {//進入循環了,不停的檢測服務器FIFO是否有數據 if (buff[n-1] == '\n') n--; buff[n] = '\0';//消除傳入數據最後的換行符,改爲字符串結束符 if ((ptr = strchr(buff, ' ')) == NULL) {//傳入的數據由三部分組成,前面是與之通訊的fifo名所須要的pid號, //而後空格,最後是要處理的文件名 printf("the buff is %s\n",buff); continue; } printf("the buff is %s\n",buff); *ptr++ = '\0';//將空格改爲字符串結束符,那麼傳入的數據就變成兩個獨立的字符串了 printf("the buff is %s\n",buff); pid = atol(buff);//獲取pid號,字符轉換成int snprintf(fifoname, sizeof(fifoname), "/tmp/fifo.%ld", (long)pid);//由pid推出通訊fifo名 if ((writefifo = open(fifoname, O_WRONLY, 0)) < 0) {//以只讀模式打開通訊fifo名 printf("can't open:%s\n",fifoname); continue; } if ((fd = open(ptr, O_RDONLY)) < 0) {//打開文件 snprintf(buff+n, sizeof(buff) - n, ":can't open ,%s\n",strerror(errno)); n = strlen(ptr); write(writefifo, buff, n); close(writefifo); } else { while ((n = read(fd, buff, MAXLINE)) > 0) //獲取文件內容 write(writefifo, buff, n);//將文件內容寫入通訊fifo去 //mainclient.c #include <stdio.h> #include <stdlib.h> #include <sys/stat.h> #include <sys/types.h> #include <string.h> #include <errno.h> #include <unistd.h> #include <fcntl.h> #define MAXLINE 1000 #define FILEMODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP) #define SERV_FIFO "/tmp/serv_fifo" int main(int argc, char **argv) { int readfifo, writefifo; size_t len; ssize_t n; char *ptr, fifoname[MAXLINE], buff[MAXLINE]; pid_t pid; pid = getpid();//獲取本客戶端的pid號 snprintf(fifoname, sizeof(fifoname), "/tmp/fifo.%ld", (long)pid);//造成本客戶端通訊的fifo名 if ((mkfifo(fifoname, FILEMODE) < 0) && (errno != EEXIST)) { printf("can't create %s\n",fifoname); exit(1); } snprintf(buff, sizeof(buff), "%ld", (long)pid);//將pid格式化到buf去,以便後面將此buf寫入到服務器fifo去 len = strlen(buff); ptr = buff + len; *ptr = ' ';//pid後加一個空格,以示區分 ptr++; fgets(ptr, MAXLINE - len, stdin);//獲取從標準輸入裏獲得的文件路徑名,同時寫入到buf去 len = strlen(buff); writefifo = open(SERV_FIFO, O_WRONLY, 0); write(writefifo, buff, len);//將此buf發送到服務器端FIFO文件去 readfifo = open(fifoname, O_RDONLY, 0);//只讀模式打開客戶端通訊fifo while((n = read(readfifo, buff, MAXLINE)) > 0)//等待讀取服務器端反饋的數據 write(STDOUT_FILENO, buff, n);//講數據寫道標準輸出裏 close(readfifo); unlink(fifoname); exit(0); }
close(fd); close(writefifo); } } exit(0); }