簡體   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