2017-10-19 149 views
0

基本上我希望我的客户端程序从文件(命令行输入中指定的文件名/路径)读取数据并将该数据复制到FIFO,并且我希望我的服务器程序从FIFO中读取并打印每一行。命名PIPE(FIFO)读取文件的内容C

例如,如果我想打印/ etc/passwd文件的文本文件,我在这样的终端上运行程序的内容:

./server & 
./client < /etc/passwd 

然而,不是打印任何输出,它打印出只有'完成'了。 为什么?
这里是我的代码:
server.c

//server.c 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 

#define FIFONAME "myfifo" 

int main(void){ 

    int n,fd; 
    char buffer[1024]; 
    unlink(FIFONAME); 

    //create FIFO 

    if(mkfifo(FIFONAME,0666)<0){ 
     perror("server: mkfifo"); 
     exit(1); 
    } 
    //open FIFO for reading 
    if((fd = open(FIFONAME, O_RDONLY))<0){ 
     perror("server: open"); 
     exit(1); 
    } 
    //READ from fifo UNTIL end of tile and print 
    //what we get on the standard input 
    while((n=read(fd,buffer,sizeof(buffer)))>0){ 
     write(1, buffer, n); 
    } 

    close(fd); 
    exit(0); 
} 


client.c

//client.c 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <string.h> 

#define FIFONAME "myfifo" 

int main(void){ 

    int n,fd; 
    char buffer[1024]; 

    /* open, read, and display the message from the FIFO */ 
    if((fd = open(FIFONAME, O_WRONLY))<0){ 
     perror("client: open"); 
     exit(1); 
    } 
    //read from standard input and copy data to the FIFO 
    while (fgets(buffer, sizeof(buffer), stdin) != 0){ 
     fgets(buffer, sizeof(buffer), stdin); 
     write(fd, buffer, n); 
    } 


    close(fd); 
    exit(0); 
} 
+0

您确定服务器有时间在客户端启动之前创建FIFO(这将在客户端创建一个常规文件) –

+0

@ Jean-FrançoisFabre的确,在客户端开始之前它确实有足够的时间来创建FIFO ! – fredjohnson

+0

你可以在服务器和客户端之间添加一个“睡眠”吗?花费不大,但值得一试。 –

回答

2

这个代码是错误的:

while (fgets(buffer, sizeof(buffer), stdin) != 0){ 
     fgets(buffer, sizeof(buffer), stdin); 
     write(fd, buffer, n); 

这个循环消耗的输入,然后再读取它。你失去了第一个(也可能是唯一的)buffer。我会做(也许不是最好的代码,但工程):

while (1){ 
     if (fgets(buffer, sizeof(buffer), stdin)==0) break; 
     write(fd, buffer, n); 
} 

除此之外,在我的评论中指出,运行在后台创建FIFO和运行客户端的服务器,而无需等待FIFO中创建的潜在的竞争条件。

+0

谢谢你的回答!我在客户端程序中按照您的建议在客户端程序中添加了2秒的睡眠时间,但仍会打印出“已完成”并且没有输出文本文件。 ' int n,fd; char buffer [1024];睡眠(2);打开,读取并显示来自FIFO的消息*/ '//在客户端文件 – fredjohnson

+0

中增加了睡眠呀,但是您是否完全阅读了我的答案?您的客户端代码是_wrong_ –

+0

是的,这是错误的,因此我已将我的客户端代码更改为您在我的文本编辑器中建议的代码。 – fredjohnson