FIFO单个服务器多个客户

本文介绍了一种服务器与客户端间基于FIFO文件进行文件路径名及文件内容传输的方法。服务器通过SERV_FIFO文件接收客户端发来的文件信息,并将其与对应的fifo文件关联,从而实现高效的数据交换。客户端则通过读取服务器提供的fifo文件,获取并显示所需文件内容。

例子:服务器只通过SERV_FIFO文件获取各个客户端发过来的文件路径名以及与此客户端通信的fifo文件名(由/tmp/fifo.pid组成,这里所需要的就是客户端的pid号)。服务器把文件打开后,将文件内容输入与此客户端通信的fifo,最后客户端从此fifo获取文件内容,然后输出到标准输出。

代码:

//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);
}

转载于:https://my.oschina.net/u/178323/blog/32180

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值