c++ 将std::future与asio::async_connect一起使用

mzsu5hc0  于 2023-01-10  发布在  其他
关注(0)|答案(1)|浏览(177)

我正在使用asio库,我正在尝试连接到一个套接字。有时候,套接字可能需要很长时间才能连接。在这种情况下,我只想取消连接。
我尝试使用带有异步操作std::futureasio::use_future来完成这个任务,我的想法是用asio::use_future()调用asio::ip::tcp::socket的成员函数async_connect(),然后调用wait_for(),等待std::future并检查它是否就绪或超时。
如果超时,我将取消(返回false),如果就绪,我将继续工作。但是,如果我尝试使用wait_for()并等待操作,它将永远不会就绪(它几乎看起来好像从未运行过,但不知道如何验证)。运行相同的代码而不使用std::future似乎工作正常,但我将无法强制超时。
这是我试过的密码。

asio::ip::tcp::endpoint endpoint(asio::ip::make_address(peer.address, ec), peer.port);

        if (ec)
        {
            std::cout << ec.message() << std::endl;
            return false;
        }

        asio::io_context context;

        asio::ip::tcp::socket socket{context};

        std::chrono::milliseconds span(100);

        std::future<void> connect_status = socket.async_connect(endpoint, asio::use_future);

        if (connect_status.wait_for(span) == std::future_status::timeout)
            return false;

        connect_status.get();
3qpi33ja

3qpi33ja1#

asio::io_context负责执行任何异步工作。为了让它执行这些工作,您必须运行context.run()
例如,参见:https://www.boost.org/doc/libs/1_81_0/doc/html/boost_asio/example/cpp11/futures/daytime_client.cpp.
代码的修复版本为:

asio::ip::tcp::endpoint endpoint(asio::ip::make_address(peer.address, ec), peer.port);

if (ec)
{
    std::cout << ec.message() << std::endl;
    return false;
}

asio::io_context context;
auto work = boost::asio::make_work_guard(context);
std::thread thread([&context](){ context.run(); });

asio::ip::tcp::socket socket{context};

std::chrono::milliseconds span(100);

std::future<void> connect_status = socket.async_connect(endpoint, asio::use_future);

if (connect_status.wait_for(span) == std::future_status::timeout)
    return false;

connect_status.get();

相关问题