繁体   English   中英

boost :: beast同步HTTP客户端超时

[英]Timeout for boost::beast sync http client

我正在通过Boost Beast示例改编同步HTTP客户端 不幸的是,示例客户端不包含超时选项,有时会卡在我的工作负载中。 我尝试添加超时

beast::get_lowest_layer(stream).expires_after(NetworkSettings::BASIC_TIMEOUT);

在调用写/读操作之前,但是这些仅在使用async_read / write时才起作用。 根据我的发现 ,似乎基本的boost asio仅支持异步操作超时。 所以我的问题是,野兽是否有任何能力在阻止连接/读取/写入调用时使用超时。

超时不适用于Asio中的同步I / O。 由于Beast在asio之上,因此它也不支持同步I / O超时。 如果要超时,则必须使用异步API。 您可以使用堆栈式协程,或者如果您具有足够现代的编译器,则可以尝试无co_await协程( co_await )。 这些使您可以编写显示为同步但使用异步接口的代码。

Beast文档对此很明确: “出于可移植性的原因,网络不提供同步流操作的超时或取消功能。”

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

如果要在连接操作上超时,请使用beast::tcp_stream实例并调用async_connect成员函数: https : async_connect /using_io/timeouts.html#beast.using_io.timeouts.connecting

您可以使用类似这样的东西。

尝试将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指定在报告错误之前接收或发送超时。 该参数是一个struct timeval。 如果输入或输出功能在这段时间内处于阻塞状态,并且已经发送或接收了数据,则该功能的返回值将是传输的数据量; 如果未传输任何数据且已达到超时,则将errno设置为EAGAIN或EWOULDBLOCK或EINPROGRESS(对于connect(2)),将返回-1,就像将套接字指定为非阻塞一样。 如果超时设置为零(默认值),则操作将永不超时。 超时仅对执行套接字I / O的系统调用有效(例如read(2),recvmsg(2),send(2),sendmsg(2)); 超时对select(2),poll(2),epoll_wait(2)等无效。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM