2013-05-02 51 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结束之前收到数据并且没有数据再次到达的情况)之后退出。