我用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