例子:服务器只经过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); }