boost :: Beast Sync http客户端的超时

Timeout for boost::beast sync http client

本文关键字:超时 客户端 Sync Beast boost http      更新时间:2023-10-16

我正在从Boost Beast示例中调整同步HTTP客户端。不幸的是,示例客户端不包括超时选项,有时会陷入我的工作量中。我尝试使用

添加超时
beast::get_lowest_layer(stream).expires_after(NetworkSettings::BASIC_TIMEOUT);

在调用写入/读取操作之前,但是使用async_read/write时,这些操作似乎只能工作。据我发现,似乎基本的Boost Asio仅支持异步操作的超时。所以我的问题是,野兽是否有任何功能在封锁连接/读/写呼叫上使用超时。

超时不适用于ASIO的同步I/O。由于野兽是ASIO上方的一层,因此它也不支持同步I/O的超时。如果需要超时,则必须使用异步API。您可以使用堆叠的Coroutine,或者如果您有足够的现代编译器,则可以尝试使用无型Coroutines(co_await(。这些允许您编写出现同步但使用异步接口的代码。

野兽文档对此很清楚:"出于可移植性原因,网络不提供同步流操作的超时或取消功能。"

https://www.boost.org/doc/libs/1_70_0/libs/beast/doc/html/beast/beast/using_io/time_io/timeouts.html

如果您想在连接操作上有超时,请使用beast::tcp_stream的实例并调用async_connect成员函数:

您可以使用类似的东西。

尝试将stream.connect(results)更改为

auto Future = stream.async_connect(endpoint, net::use_future);
if(Future.wait_for(std::chrono::seconds(1)) == std::future_status::timeout){
   std::cout<<"timed_out";
   ....
}else {
}

要注意的一堆东西:

1(您可能需要下面的标头文件

#include<boost/asio/use_future.hpp>
#include<chrono>
#include<future>

2(由于您是asyc_*启动;您需要致电ioc.run();

3(您需要另一个线程来执行ioc.run();,因为我们通过异步嘲笑同步 - 有人必须运行事件 - 循环。

另一种方法:您可以使用其本机句柄明确设置套接字选项(我从未做过(。但是在此之前,请阅读此答案https://stackoverflow.com/a/51850018/5198101

const int timeout = 200;
::setsockopt(socket.native_handle(), SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout, sizeof timeout);//SO_SNDTIMEO for send ops

https://linux.die.net/man/7/socket

so_rcvTimeo和so_sndtimeo指定接收或发送超时 直到报告错误。该论点是一个结构时空。如果 此期间的输入或输出功能块,数据具有 已发送或接收,该功能的返回值将是 传输的数据量;如果没有传输数据,并且 已经到达超时了,然后将errno设置为eagain返回-1 或ewoldblock或einprogress(对于连接(2((,就像插座一样 被指定为非块。如果超时设置为零( 默认值(然后操作将永远不会超时。超时只有 对执行插座I/O的系统调用的效果(例如,读(2(, RECVMSG(2(,send(2(,sendmsg(2((;超时没有影响 选择(2(,民意调查(2(,epoll_wait(2(等等。