我用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);
我用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);
作爲一種替代方法,您可以使用setsockopt
和SO_RCVTIMEO
選項來設置超時插座。這將影響對其執行的所有讀取操作。
在這裏看到:http://permalink.gmane.org/gmane.linux.man/3440
基本上超時參數指定的最大時間量等待更多的消息,但底層接收操作仍然阻塞。因此,如果您將超時設置爲5秒並每秒接收一條消息,則即使在緩衝區中有空間以獲取更多消息,它也會在收到(約)5條消息後停止。如果根本沒有數據,5秒後它將不會返回。爲此,您應該使用通常的機制之一,如select()或epoll()超時或忙等待等。
我無法真正想象一個用例,這是有用和有意的。 – PlasmaHH 2013-10-16 15:52:25
從這個答案的鏈接,我發現一個報價是非常說明性的「recvmmsg()有一個明確的超時參數,但它看起來不像 正常工作,文檔沒有提及它應該如何與SO_RCVTIMEO交互。 「這是有幫助的,因爲它解釋了爲什麼你必須設置套接字的'SO_RCVTIMEO'參數,如果你想'recvmmsg()'timeout參數不能無限期地阻塞。 (我的recvmmsg測試代碼(來自'man recvmmsg')無限期地阻塞,超時時間爲1秒。如果你設置了套接字的SO_RCVTIMEO,那麼它不會無限期地阻塞。) – 2015-02-05 18:24:01
有臭蟲的recvmmsg實現:
通知,pselect
允許你檢查數據是否可用。但是,不保證recvmmsg
不會永遠等待。因此,不要使用這種方法。
我建議你使用加上timeout
參數recvmmsg。如果自SO_RCVTIMEO
或timeout
之後沒有收到數據,recvmmsg將退出。在最壞的情況下,recvmmsg將在timeout
+ SO_RCVTIMEO
(在timeout
結束之前收到數據並且沒有數據再次到達的情況)之後退出。
這裏有一個可能的錯誤,可能是相關的建議:http://lists.openwall.net/netdev/2012/12/23/30 – Vicky 2013-05-02 15:12:36
@Vicky:這是關於正確的 - 類似於我的鏈接回答。然而,並不清楚任何人都會改變這種行爲 - 更可能的是它會被視爲文檔錯誤,手冊頁將被更新,並且幾乎沒有用處的超時參數將不會被大多數應用程序使用。 – 2013-05-02 15:15:59
在上面的鏈接使用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