C++: boost::asio: async_resolve() 不起作用(使用 lambda 函数),但 resolve() 有效

C++: boost::asio: async_resolve() doesn't work (with lambda functions), but resolve() works

本文关键字:resolve 函数 lambda 使用 有效 不起作用 async C++ boost asio      更新时间:2023-10-16

根据这个例子,我的程序中有这样的同步初始化部分:

io_service = new boost::asio::io_service;
resolver   = new boost::asio::ip::tcp::resolver(*io_service);
query      = new boost::asio::ip::tcp::resolver::query(data.serverAddress.c_str(),data.serverPort.c_str());
iterator   = resolver->resolve(*query);
//...

现在这工作得很好,没有任何问题,除了如果没有连接,调用resolver->resolve(*query);无限阻塞。为了解决这个问题,我决定使用resolver->async_resolve(*query);代替。因此,我编写了以下代码来与lambda函数同步操作,因此以下代码替换了前代码的最后一条语句:

    boost::system::error_code queryError;
    boost::function<void(const boost::system::error_code&,const boost::asio::ip::tcp::resolver::iterator&)> queryLambda =
            [&querySuccess,&queryError,this]
            (const boost::system::error_code& errorCode, const boost::asio::ip::tcp::resolver::iterator& it)
    {std::cout<<"Success!"<<std::endl;querySuccess=1;iterator=it;queryError=errorCode;};
    resolver->async_resolve(*query,queryLambda);

    int timeout = 10000;
    int totalTime = 0;
    int timeWaitStep = 1000;
    while(true)
    {
        std::cout<<"Trying to connect..."<<std::endl;
        sleep(timeWaitStep);
        if(querySuccess)
        {
            break;
        }
        else
        {
            totalTime += timeWaitStep;
            std::cout<<totalTime<<std::endl;
            if(totalTime > timeout)
            {
                throw std::domain_error("Unable to connect to server. Make sure you have a valid connection.");
            }
        }
    }
当同步代码在瞬间连接时,异步代码永远不会连接。我做错了什么?

谢谢你的努力

你应该run工作的地方,使用io_service::run功能,或io_service::poll。顺便说一句,如果你想用resolve超时,你应该使用deadline_timerasync_wait

Asio发出一个异步操作意味着你把它安排在io_service内部调用;除非您告诉io_service它应该开始轮询网络,执行预定的操作并调用回调,否则所有这些操作都不会发生。这就是像io_service::pollio_service::run这样的方法所做的。

最简单的方法是在调用async_resolve之后调用io_service::run:

...
resolver->async_resolve(*query,queryLambda);
io_service->run();