【问题标题】:boost.asio boost::asio::ip::tcp::resolver::async_resolve doesn't workboost.asio boost::asio::ip::tcp::resolver::async_resolve 不起作用
【发布时间】:2013-02-16 09:32:26
【问题描述】:

我按照 Boost.Asio 教程实现了一个简单的 TCP 客户端,但是我在第一步被阻止了,boost::asio::ip::tcp::resolver::async_resolve 不起作用,ResolverHandler 永远不会被调用:

    void client::start()
    {
        socket_.reset(new boost::asio::ip::tcp::socket(io_service_));
        // Start an asynchronous resolve to translate the server and service names
        // into a list of endpoints.
        tcp::resolver::query query(server_address_, server_port_);
        resolver_.async_resolve(query,
            boost::bind(&client::handle_resolve, 
            shared_from_this(),
            boost::asio::placeholders::error,
            boost::asio::placeholders::iterator));
    }

如上所示的源代码,我创建了一个io_service、一个socket、一个resolver和一个解析器query对象,然后调用resolver_.async_resolve()方法,但是ResolverHandler client::handle_resolve几乎从来没有调用,有时在应用程序第一次启动时,可能会调用 ResolverHandler 一两次,但仅此而已。

我阅读了官方文档,但一无所获。有什么建议吗?

【问题讨论】:

  • server_address_ & server_port_ 应该可用,例如“localhost” & “25166”。
  • 我认为你的 tcp::resolver::query 在函数退出时被破坏了。
  • @PSIAlt async_resolve() copies tcp::resolver::query 对象
  • @Fan Yang 发了一个sscce 来演示这个问题。我想看看你的client::handle_resolve() 方法。另请注意,async_resolve() 在大多数(所有?)平台上通常是emulated,每个io_service 都有一个线程。
  • 如果完成处理程序没有被调用——很可能你没有正确运行io_service。显示io_service相关代码。

标签: c++ sockets boost boost-asio


【解决方案1】:

如果完成处理程序没有被调用——很可能你没有正确运行io_service:例如。它的run 循环可能被其他一些没有返回的处理程序阻塞,或者它可能由于缺少工作等而退出。

【讨论】:

    【解决方案2】:

    这对我有用:

    void SSLSocket::Connect(SSLSocket* psSLS, const string& serverPath, const string& port)
    {
       boost::shared_ptr<boost::asio::io_service> IOServ(new boost::asio::io_service);
       // Create the resolver and query objects to resolve host name in serverPath to an ip address.
       IOService = IOServ; // IOService defined as a class member in the .h file.
       boost::asio::ip::tcp::resolver resolver(*IOService);
       boost::asio::ip::tcp::resolver::query query(serverPath, port);
       ...
    }
    

    以上代码使用的是同步方式.vs。您的代码正在使用的异步方法。如果要继续异步执行,则将 io_service 对象和查询对象设为类变量。还要意识到 async_resolve 方法会立即返回而无需执行任何操作。地址被异步解析,之后你的 handle_resolve 方法被调用。

    【讨论】:

    • 将具有自动存储持续时间的tcp::resolver::query 传递给async_resolve()just fine,底层服务将根据需要复制该对象。
    • Unicode 意识,默认为 const,自动引用计数,默认传递引用,默认为 COW,列出一些好的字符串类。
    猜你喜欢
    • 1970-01-01
    • 2018-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多