2013-05-02 291 views
5

我用c構建了一個簡單的應用程序,它使用了recvmmsg(),第五個參數是type struct timespec。我將超時設置爲5秒,但它不工作,它阻止了無窮大。如何在recvmmsg()中設置超時?

的代碼如下所示:

struct timespec timeout; 

timeout.tv_sec = 5; 
timeout.tv_nsec = 0; 

result = recvmmsg(fd, datagrams, BATCH_SIZE, 0, &timeout); 
+1

這裏有一個可能的錯誤,可能是相關的建議:http://lists.openwall.net/netdev/2012/12/23/30 – Vicky 2013-05-02 15:12:36

+0

@Vicky:這是關於正確的 - 類似於我的鏈接回答。然而,並不清楚任何人都會改變這種行爲 - 更可能的是它會被視爲文檔錯誤,手冊頁將被更新,並且幾乎沒有用處的超時參數將不會被大多數應用程序使用。 – 2013-05-02 15:15:59

+0

在上面的鏈接使用select有另一種解決方案:http://stackoverflow.com/questions/12713438/how-to-add-delay-to-sento-and-recvfrom-in-udp-client-server-in- c – MOHAMED 2013-05-02 17:01:25

回答

4

作爲一種替代方法,您可以使用setsockoptSO_RCVTIMEO選項來設置超時插座。這將影響對其執行的所有讀取操作。

5

在這裏看到:http://permalink.gmane.org/gmane.linux.man/3440

基本上超時參數指定的最大時間量等待更多的消息,但底層接收操作仍然阻塞。因此,如果您將超時設置爲5秒並每秒接收一條消息,則即使在緩衝區中有空間以獲取更多消息,它也會在收到(約)5條消息後停止。如果根本沒有數據,5秒後它將不會返回。爲此,您應該使用通常的機制之一,如select()或epoll()超時或忙等待等。

+0

我無法真正想象一個用例,這是有用和有意的。 – PlasmaHH 2013-10-16 15:52:25

+0

從這個答案的鏈接,我發現一個報價是非常說明性的「recvmmsg()有一個明確的超時參數,但它看起來不像 正常工作,文檔沒有提及它應該如何與SO_RCVTIMEO交互。 「這是有幫助的,因爲它解釋了爲什麼你必須設置套接字的'SO_RCVTIMEO'參數,如果你想'recvmmsg()'timeout參數不能無限期地阻塞。 (我的recvmmsg測試代碼(來自'man recvmmsg')無限期地阻塞,超時時間爲1秒。如果你設置了套接字的SO_RCVTIMEO,那麼它不會無限期地阻塞。) – 2015-02-05 18:24:01

0

有臭蟲的recvmmsg實現:

通知,pselect允許你檢查數據是否可用。但是,不保證recvmmsg不會永遠等待。因此,不要使用這種方法。

我建議你使用加上timeout參數recvmmsg。如果自SO_RCVTIMEOtimeout之後沒有收到數據,recvmmsg將退出。在最壞的情況下,recvmmsg將在timeout + SO_RCVTIMEO(在timeout結束之前收到數據並且沒有數據再次到達的情況)之後退出。