2017-10-19 204 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