![](/img/trans.png)
[英]Problems making a sync http request through proxy using Boost Beast
[英]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.