2011-02-08 32 views
2

我正在構建客戶端/服務器模型,但使用帶有mkfifo()的命名管道的套接字。如何在未遇到EOF時終止read()?

客戶端輸出寫入命名管道,和我讀使用我的服務器輸入:

while ((n = read(fd_in, &newChar, 1)) == 1) { /* ... */ } 

我每次讀一個字符,直到我遇到了兩個大字:<「CR」 > <'LF'>。我想以這樣的方式編寫我的代碼,如果客戶在一段時間後不終止<'CR'> <'LF'>,我可以丟棄它並繼續到另一個客戶端,否則下一個客戶端將擁有等待,也許無限。

有沒有辦法請終止執行read()?如果它在2秒內沒有返回,我可以說中斷讀取並丟棄之前讀取的字符,並重新開始閱讀?

感謝你的幫助,

Jary

+1

也許在非阻塞模式下讀取並設置計時器到期? – Peyman 2011-02-08 00:26:33

回答

3

嘗試通過O_NONBLOCK標誌當您的open FIFO的讀取結束。這應該改變行爲,以便read立即返回,即使請求的字符數不在管道中。

+0

謝謝,這是一個不錯的,非常簡單的解決方案。我有時得到錯誤讀:資源暫時不可用(因爲我的while循環),但否則這是一個很好的解決方案,謝謝。 – Jary 2011-02-08 01:57:51

4
#include <stdbool.h> 
#include <poll.h> 

do { 
    ssize_t ret; 
    struct pollfd ps = {.fd = fd_in, .events = POLLIN}; 

    if (poll(&ps, 1, 2000) < 0) 
     break; /* kick client */ 
    ret = read(in_fd, ...); 
    if (ret != 1) 
     break; 
    /* process read data */ 
} while (true); 

此檢查是否存在要讀取的數據;如果沒有在2000毫秒內,請做任何你想要的(例如斷開連接)。

+0

謝謝你的解決方案真的很棒。非常感謝,它完美地解決了我的問題。謝謝。 – Jary 2011-02-08 01:58:46

1

要同時處理多個客戶端,你應該設置文件描述符無阻塞fcntl(),然後用select()poll()阻塞,直到輸入出現在它們中的至少一個。