FIFO单个服务器多个客户

例子:服务器只经过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);
}
相关文章
相关标签/搜索