![](/img/trans.png)
[英]Boost::asio socket - how to make read_some 'throw' in “timeout”?
[英]How to make a timeout at receiving in boost::asio udp::socket?
我創建了一個單線程應用程序,它通過 UDP 與另一個線程交換。當第二個應用程序斷開連接時,我的 socket::receive_from 阻塞了,我不知道如何解決這個問題,而不是將整個程序更改為多線程或異步交互.
我認為接下來可能是一個解決方案:
std::chrono::milliseconds timeout{4};
boost::system::error_code err;
data_t buffer(kPackageMaxSize);
std::size_t size = 0;
const auto status = std::async(std::launch::async,
[&]{
size = socket_.receive_from(boost::asio::buffer(buffer), dst_, 0, err);
}
).wait_for(timeout);
switch (status)
{
case std::future_status::timeout: /*...*/ break;
}
但是我遇到了一個新問題: Qt Creator (GDB 11.1) (我還沒有能力嘗試一些東西)在我調試時開始下降。 如果它沒有運行,解決方案也不總是有效。
附言。 至於“調試時不起作用”,調試(特別是斷點)顯然會改變時序。 此外,請記住。網絡操作具有不同的延遲,並且 UDP 不是有保證的協議:消息可能無法傳遞。
Asio 代表“異步 IO”。 您可能會懷疑,這意味着異步 IO 是一項內置功能,它是該庫的全部目的。 參見 overview/core/async.html: 沒有線程的並發
沒有必要使std::async
復雜化。 在你的情況下,我建議使用async_receive_from
和use_future
,因為它最接近你選擇的 model :
#include <boost/asio.hpp>
#include <iostream>
#include <iomanip>
namespace net = boost::asio;
using net::ip::udp;
using namespace std::chrono_literals;
constexpr auto kPackageMaxSize = 65520;
using data_t = std::vector<char>;
int main() {
net::thread_pool ioc;
udp::socket socket_(ioc, udp::v4());
socket_.bind({{}, 8989});
udp::endpoint ep;
data_t buffer(kPackageMaxSize);
auto fut =
socket_.async_receive_from(net::buffer(buffer), ep, net::use_future);
switch (fut.wait_for(4ms)) {
case std::future_status::ready: {
buffer.resize(fut.get()); // never blocks here
std::cout << "Received " << buffer.size() << " bytes: "
<< std::quoted(
std::string_view(buffer.data(), buffer.size()))
<< "\n";
break;
}
case std::future_status::timeout:
case std::future_status::deferred: {
std::cout << "Timeout\n";
socket_.cancel(); // stop the IO operation
// fut.get() would throw system_error(net::error::operation_aborted)
break;
}
}
ioc.join();
}
大腸桿菌 output:
Received 12 bytes: "Hello World
"
在本地演示超時和成功路徑:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.