2011-11-29 79 views
1

我嘗試通過TCP套接字進行一種聊天。服務器端在PHP和(應該)工作正常。雙向插座(非阻塞)與c

不,我遇到了在客戶端的問題(用C語言實現[C99]):

我想聽聽(讀取)來自服務器的「新字節」,我也想每當用戶輸入新數據時向服務器發送(寫入)「一些字節」。

現在的問題: - >我如何監聽傳入流量(讀取),仍然能夠每1秒調用一次回調,我可以檢查發送給服務器的新字節? 我知道我必須使用select(系統調用),但我不知道如何處理超時等選擇也阻止了一定的時間。

感謝您的任何示例。

+0

您是否考慮過使用線程? –

+0

線程將以不好的方式解決問題。 –

回答

1

有一個函數叫做select,可以用於這個。它可以檢查套接字是否有新的輸入來讀取,並且它有一個超時時間,所以它也可以用於你的定時器。

它存在於所有主要操作系統上的一種形式或其他形式。只要做一個谷歌搜索socket select <your operating system> example,你會得到一個船載的結果。


select的最後一個參數用於超時。它是一個指向struct timeval的指針,該結構包含設置超時的字段。

如果該指針作爲NULL傳遞,那麼沒有超時,並且select可以無限期地阻塞。

要設置超時,你需要將timeval結構的tv_sec字段設置爲秒數,和tv_usec場微秒數(必須小於一百萬)。通過將這些字段設置爲零,您可以將超時設置爲零,即僅進行快速輪詢。如果select返回零,則出現超時。

實施例,用1.5秒的超時:

for (;;) 
{ 
    fd_set readset; 
    int maxfd; 

    /* Initialize and set `readset` and `maxfd` */ 

    struct timeval tv; 
    tv.tv_sec = 1; 
    tv.tv_usec = 500000; 

    int res = select(maxfd + 1, &readset, NULL, NULL, &tv); 

    if (res == -1) 
     perror("select"); /* Error */ 
    else if (res == 0) 
    { 
     /* Timeout, do something */ 
    } 
    else 
    { 
     /* A socket in `readset` is readable */ 
    } 
} 

如果select返回之前超時,則timeval結構被修改,以包含剩餘的超時時間。

+0

謝謝。我知道我必須使用select。但我如何設置超時?選擇也阻止....任何想法的例子?我無法通過Google搜索找到c的示例。 –

+0

找到了解決方案! http://rhoden.id.au/doc/sockets。html –

+0

您還發現一個斷開的鏈接! – g33kz0r

0

使用系統調用select,並根據需要設置timeout參數。有很多示例代碼, Beej's guide仍然是一個很好的來源。