2017-04-13 36 views
0

我想創建一個服務器進程和一個客戶端進程 - 用於可選的類分配 - 並使它們相互通信。這位教授告訴我們:用於寫入的開放FIFO返回「沒有這樣的設備或地址」

1)我們必須使用O_NONBLOCK

2)我們必須創建2個FIFO,一個僅用於閱讀和一個只寫

3)我們不能使用套接字

所以,我在服務器進程中創建了2個FIFO,我試圖打開它們,但是打開WRONLY返回「沒有這樣的設備或地址」。

服務器進程:

...... 

if(mkfifo("fifo1", PERMS) < 0 && errno != EEXIST) 
{ 
    perror("can't create FIFO (read)"); 
    exit(EXIT_FAILURE); 
} 
if(mkfifo("fifo2", PERMS) < 0 && errno != EEXIST) 
{ 
    perror("can't create FIFO (write)"); 
    exit(EXIT_FAILURE); 
} 

if((readfd = open("fifo1", O_RDONLY | O_NONBLOCK)) < 0) 
{ 
    perror("console: can't open read FIFO"); 
    exit(EXIT_FAILURE); 
} 
if((writefd = open("fifo2", O_WRONLY | O_NONBLOCK)) < 0) 
{ 
    perror("coord: can't open write FIFO"); 
    exit(EXIT_FAILURE); 
} 

客戶端進程:

..... 

if((readfd = open("fifo2", O_RDONLY | O_NONBLOCK)) < 0) 
{ 
    perror("console: can't open read FIFO"); 
    exit(EXIT_FAILURE); 
} 
if((writefd = open("fifo1", O_WRONLY | O_NONBLOCK)) < 0) 
{ 
    perror("console: can't open write FIFO"); 
    exit(EXIT_FAILURE); 
} 

while(fgets(buffer, 100, stdin)) //char buffer[100]; 
{ 
    n = strlen(buffer); 
    w = write(writefd, buffer, n); 

    memset(buffer, 0, 100); 
} 

我找了一個解決方案在網上,我發現this答案,這也解釋了精細什麼不順心,但沒有按提出一種解決問題的方法。我再次在線看,發現select(),它看起來像它可以提供一個解決方案,但我有一些麻煩,理解它的工作原理。

是否可以使用select()爲了解決這個問題?

回答

0

除非讀取器已經打開FIFO,否則您無法打開FIFO進行無阻塞寫入。最簡單的方法是等待一秒鐘,如果返回ENXIO,則重複open。重複,直到另一方運行。

+0

所以,你提出了一個簡單的while(1)或for(;;)循環,其中打開寫入內部。我認爲這是一個很好的解決方法,因爲它在開始時只發生一次。謝謝 –

+0

@FotisSk是的。添加評論,解釋理由,以及爲什麼不值得更多努力。 –

+0

是的,我會的。順便說一下,剛剛向我提出的一些問題。如果讀取(或其他一些隨機命令)返回-1以忽略它並再次讀取,那麼它是否「OK」?在此先感謝您的幫助!! –

1

一個直接的解決方案是open FIFO用於在阻斷模式寫入(它會被阻塞,直到另一端是敞開的閱讀),並使其非阻塞算賬:

writefd = open(fifo_name, O_WRONLY); 
    fcntl(writefd, F_SETFL, O_NONBLOCK); 

PS:我強烈反對忙着等。

+0

非常優雅的解決方案。謝謝! –

相關問題