在 async_resolve 上取消操作

ole*_*man 3 c++ boost-asio c++11

我对 C++ 有一些小经验,并且在使用 boost-asio 时遇到了一些问题。我想重写标准升压ASIO异步HTTP客户端的例子(http://www.boost.org/doc/libs/1_58_0/doc/html/boost_asio/example/cpp03/http/client/async_client.cpp中)以下方式。

我的目标是有 2 个班级;

  1. AsyncHttpClient(存储主机并具有将异步调用发送到指定路径的成员函数)。
  2. AsyncHttpConnection(以 io_service、host、path 作为参数并遵循 boost-asio async-http-client 示例中指定的流程)

我有以下实现

using boost::asio::ip::tcp;

class AsyncHttpConnection {
    public:
        AsyncHttpConnection(
            boost::asio::io_service& io_service,
            std::string host,
            std::string path) : resolver_(io_service),
                                socket_(io_service),
                                host_(host),
                                path_(path)
        {
            tcp::resolver::query query(host_, "http");
            resolver_.async_resolve(query,
                boost::bind(&AsyncHttpConnection::handle_resolve,
                    this,
                    boost::asio::placeholders::error,
                    boost::asio::placeholders::iterator));
        }

    private:
        std::string host_;
        std::string path_;
        tcp::resolver resolver_;
        tcp::socket socket_;
        boost::asio::streambuf request_;
        boost::asio::streambuf response_;

        void handle_resolve(
            const boost::system::error_code& err,
            tcp::resolver::iterator endpoint_iterator)
        {
            if (!err) {
                // code here
            } else {
                std::cout << err.message() << std::endl; // GOT "Operation Canceled" here
            }
        }

        // list of other handlers

};

class AsyncHttpClient {
    public:
        AsyncHttpClient(
            boost::asio::io_service& io_service,
            std::string host) : host_(host)
        {
            io_service_ = &io_service; // store address of io_service
        }

        void async_call(std::string path)
        {
            AsyncHttpConnection(*io_service_, host_, path);
        }

    private:
        std::string host_;
        boost::asio::io_service* io_service_; // pointer, because io_service is uncopyable; 
};

int main(int argc, char* argv[])
{
    boost::asio::io_service io_service;
    AsyncHttpClient boost(io_service, "www.boost.org");
    boost.async_call("/doc/libs/1_51_0/doc/html/boost_asio/example/http/client/async_client.cpp");
    io_service.run();
}
Run Code Online (Sandbox Code Playgroud)

我以这种特殊方式收到错误“操作已取消”;如果我以下列方式实例化 AsyncHttpConnection

int main(int argc, char* argv[])
{
    boost::asio::io_service io_service;
    AsyncHttpConnection(io_service, "www.boost.org", "path");
    io_service.run();
}
Run Code Online (Sandbox Code Playgroud)

我一切正常,我认为问题是使用指向 io_service 的指针。如果 io_service 对象不可复制,我该如何解决这个问题?

seh*_*ehe 5

void async_call(std::string path) {
    AsyncHttpConnection(*io_service_, host_, path); 
}
Run Code Online (Sandbox Code Playgroud)

主体构造一个类型为 的临时对象AsyncHttpConnection。因此,在语句完成之前,此类型的析构函数会运行。

默认析构函数执行成员式销毁。所以它触发析构函数tcp::resolver resolver_。此类的文档指出,执行此操作时将取消任何挂起的异步操作。

原则上,“替代方案”main有完全相同的问题(实际上它Operation canceled在我的盒子上失败了)。如果它不适合您,那么您将获得非常幸运的事件时机。

  • 正如惯用修复的评论中所建议的那样,无法在构造函数中启动该操作。但是,上述修复忘记启动操作:http://coliru.stacked-crooked.com/a/17ffed95d45e69c7 (2认同)