我正在从synchronous HTTP client改写Boost Beast examples。不幸的是,示例客户端不包含超时选项,有时会卡在我的工作负载中。我尝试添加超时
beast::get_lowest_layer(stream).expires_after(NetworkSettings::BASIC_TIMEOUT);
在调用写/读操作之前,但似乎仅在使用async_read / write时起作用。 From what I found,看来基本的boost asio仅支持异步操作超时。因此,我的问题是,野兽是否具有在阻止连接/读取/写入呼叫时使用超时的功能。
答案 0 :(得分:1)
超时不适用于Asio中的同步I / O。由于Beast在asio之上,因此它也不支持同步I / O超时。如果要超时,则必须使用异步API。您可以使用堆栈式协程,或者如果您具有足够现代的编译器,则可以尝试无堆栈式协程(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://www.boost.org/doc/libs/1_70_0/libs/beast/doc/html/beast/using_io/timeouts.html#beast.using_io.timeouts.connecting
答案 1 :(得分:-1)
您可以使用类似这样的东西。
尝试将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();
,因为我们正在通过异步进行同步模拟-有人必须运行事件循环。
另一种方法:您可以使用其本机句柄(我从未做过)显式设置socket选项。但在这样做之前,请先阅读此答案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并返回-1 或EWOULDBLOCK或EINPROGRESS(用于connect(2)),就像套接字 被指定为非阻塞。如果超时设置为零( 默认值),则操作将永不超时。超时只有 对于执行套接字I / O的系统调用(例如read(2), recvmsg(2),send(2),sendmsg(2));超时对没有影响 select(2),poll(2),epoll_wait(2)等。