C++ Boost ASIO:如何读/写超时?

2021-12-11 00:00:00 sockets c++ boost-asio

通过阅读其他 Stack Overflow 条目和 boost::asio 文档,我确认没有同步 ASIO 读/写调用也提供易于使用的超时作为调用的参数.

From reading other Stack Overflow entries and the boost::asio documentation, I've confirmed that there is no synchronous ASIO read/write calls that also provide an easy-to-use timeout as a parameter to the call.

我正在使用使用超时的 select(2) 调用转换老式 Linux 套接字应用程序,我需要或多或少地做同样的事情.

I'm in the middle of converting an old-school Linux socket application with select(2) calls that employs timeouts, and I need to do more-or-less the same.

那么在 boost::asio 中执行此操作的最佳方法是什么?查看 asio 文档,有许多与计时器有关的各种事情的令人困惑的示例,但我很困惑.

So what is the best way to do this in boost::asio? Looking at the asio documentation, there are many confusing examples of various things to do with timers, but I'm quite confused.

我很想看到一个简单易读的例子:从套接字读取,但最多等待 X 秒,之后函数要么不返回任何内容,要么返回任何内容能够在超时到期之前从套接字读取.

I'd love to see a simple-to-read example of this: Read from a socket, but wait for a maximum of X seconds after which the function either returns with nothing, or returns with whatever it was able to read from the socket before the timeout expired.

推荐答案

这已在 asio 邮件列表中提出,有一个 ticket 也请求该功能.总而言之,如果您需要超时和可取消性,建议使用异步方法.

This has been brought up on the asio mailing lists, there's a ticket requesting the feature as well. To summarize, it is suggested to use asynchronous methods if you desire timeouts and cancellability.

如果您无法转换为异步方法,您可以尝试SO_RCVTIMEOSO_SNDTIMEO 套接字选项.它们可以用 setsockopt 设置,描述符可以用 boost::asio::ip::tcp::socket::native 方法.man 7 socket 手册页说

If you cannot convert to asynchronous methods, you might try the SO_RCVTIMEO and SO_SNDTIMEO socket options. They can be set with setsockopt, the descriptor can be obtained with the boost::asio::ip::tcp::socket::native method. The man 7 socket man page says

SO_RCVTIMEO 和 SO_SNDTIMEO指定接收或发送超时,直到报告错误.参数是一个结构体时间.如果输入或输出这个时期的功能块时间,并且数据已经发送或收到,该函数的返回值将是传输的数据量;如果不数据已传输并且已达到超时然后 -1 是返回 errno 设置为EAGAIN 或 EWOULDBLOCK 就像套接字被指定为是非阻塞的.如果超时是设置为零(默认)然后操作永远不会超时.超时仅有效对于执行套接字 I/O 的系统调用(例如,read(2),recvmsg(2), send(2), sendmsg(2));超时对 select(2) 没有影响,poll(2)、epoll_wait(2) 等

SO_RCVTIMEO and SO_SNDTIMEO Specify the receiving or sending timeouts until reporting an error. The argument is a struct timeval. If an input or output function blocks for this period of time, and data has been sent or received, the return value of that function will be the amount of data transferred; if no data has been transferred and the timeout has been reached then -1 is returned with errno set to EAGAIN or EWOULDBLOCK just as if the socket was specified to be non-blocking. If the timeout is set to zero (the default) then the operation will never timeout. Timeouts only have effect for system calls that perform socket I/O (e.g., read(2), recvmsg(2), send(2), sendmsg(2)); timeouts have no effect for select(2), poll(2), epoll_wait(2), etc.

相关文章