C++ boost::beast sync http客户端超时

C++ boost::beast sync http客户端超时,c++,boost,boost-asio,boost-beast,C++,Boost,Boost Asio,Boost Beast,我正在从新版本改编。不幸的是,示例客户端不包括超时选项,有时会卡在我的工作负载中。我试着把超时时间加在一起 beast::get_lowest_layer(stream).expires_after(NetworkSettings::BASIC_TIMEOUT); 在调用写/读操作之前,但这些操作似乎只在使用异步读/写时才起作用,基本boost asio似乎只支持异步操作的超时。所以我的问题是beast是否有能力在阻塞连接/读/写调用上使用超时。您可以使用类似的功能 尝试更改流。连接(结果)到

我正在从新版本改编。不幸的是,示例客户端不包括超时选项,有时会卡在我的工作负载中。我试着把超时时间加在一起

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

在调用写/读操作之前,但这些操作似乎只在使用异步读/写时才起作用,基本boost asio似乎只支持异步操作的超时。所以我的问题是beast是否有能力在阻塞连接/读/写调用上使用超时。

您可以使用类似的功能

尝试更改
流。连接(结果)

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 {

}

SO_RCVTIMEO和SO_sndtTimeo指定接收或发送超时 直到报告错误。参数是一个结构timeval。如果 此时间段的输入或输出功能块,数据 如果已发送或接收,则该函数的返回值将为 传输的数据量;如果未传输任何数据,则 已达到超时,然后返回-1,并将errno设置为EAGAIN 或eWoldBlock或EINPROGRESS(用于连接(2)),就像插座一样 已指定为非阻塞。如果超时设置为零(默认设置为零) 默认)则操作将永远不会超时。超时只有一个原因 对执行套接字I/O的系统调用的影响(例如,读取(2), recvmsg(2)、send(2)、sendmsg(2));超时对用户没有影响 选择(2)、轮询(2)、epoll_wait(2),依此类推


Asio中的同步I/O不可用超时。由于Beast是asio之上的一个层,它也不支持同步I/O超时。如果您想要超时,必须使用异步API。您可以使用堆栈式协同路由,或者如果您有足够现代的编译器,您可以尝试使用无堆栈式协同路由(
co_wait
)。这些允许您编写看似同步但使用异步接口的代码

Beast文档清楚地说明了这一点: 出于可移植性的原因,网络不为同步流操作提供超时或取消功能

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

我没有Beast方面的经验,但您是否尝试过使用
std::future
及其
wait_for
成员函数?asio库(由beast包装)支持
use\u future
,它将阻塞行为模拟为同步客户端。这将首先反驳使用异步IO的想法,对吗?@sehe-Hmmm…当然阻塞IO不是一件好事(在可伸缩性的情况下),但看起来,OP在试验同步客户端时遇到了问题,所以我给出了一个解决办法。@Explorer\N是的,因为Beast提供了一个具有超时的异步连接函数,所以不需要使用未来或非可移植套接字选项(请参阅)我已经更新了我的答案以反映这一点。@VinnieFalco,感谢您的回复,您知道,OP知道
async\u*
提供的超时操作,但他说他正在试验同步客户端,这意味着他想阻止,直到
连接发生,而且
同步con似乎没有
超时nect
这就是我建议
std::future
…当然
co_wait
也能工作,但最后,它只是另一个异步模型,如
std::future
。关于
setsockopt
——我将一个关于可移植性的答案链接起来,让OP自行决定。你仍然认为我的答案是不正确吗?@VinnieFalco,你认为
std::future
不会完成OP所寻找的工作吗?谢谢你的澄清。那么我就使用异步操作。
#include<boost/asio/use_future.hpp>
#include<chrono>
#include<future>
const int timeout = 200;
::setsockopt(socket.native_handle(), SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout, sizeof timeout);//SO_SNDTIMEO for send ops