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

发布于 2024-10-09 17:10:41 字数 345 浏览 0 评论 0原文

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

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

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

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

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.

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.

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.

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

花开浅夏 2024-10-16 17:10:41

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


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

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

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.


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 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.

伊面 2024-10-16 17:10:41

我使用了一些 asio 文档 来生成此内容:

class TimeoutAdjust
{
public:
  TimeoutAdjust(unsigned int dwTimeout) : m_dwTimeout(dwTimeout) {};

  template<class Protocol>
  int level(const Protocol& p) const {return SOL_SOCKET;}

  template<class Protocol>
  int name(const Protocol& p) const {return SO_SNDTIMEO;}

  template<class Protocol>
  const void* data(const Protocol& p) const {return &m_dwTimeout;}

  template<class Protocol>
  size_t size(const Protocol& p) const {return sizeof(m_dwTimeout);}
private:
  unsigned int m_dwTimeout;
};

用法:

TimeoutAdjust adjust(5000);
sSocket.set_option(adjust);

我调试了它,它似乎做了它应该做的事情。

I used some asio docs to produce this:

class TimeoutAdjust
{
public:
  TimeoutAdjust(unsigned int dwTimeout) : m_dwTimeout(dwTimeout) {};

  template<class Protocol>
  int level(const Protocol& p) const {return SOL_SOCKET;}

  template<class Protocol>
  int name(const Protocol& p) const {return SO_SNDTIMEO;}

  template<class Protocol>
  const void* data(const Protocol& p) const {return &m_dwTimeout;}

  template<class Protocol>
  size_t size(const Protocol& p) const {return sizeof(m_dwTimeout);}
private:
  unsigned int m_dwTimeout;
};

Usage:

TimeoutAdjust adjust(5000);
sSocket.set_option(adjust);

I debugged it, and it appears to do what it is supposed to.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文