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);
}
相關文章
相關標籤/搜索