C++ 使用boost::asio时的参考问题(我猜是这样的)

C++ 使用boost::asio时的参考问题(我猜是这样的),c++,boost,httpclient,boost-asio,C++,Boost,Httpclient,Boost Asio,我正在基于HTTP服务器上的示例构建一个HTTP客户机。现在,该代码和我的代码之间的区别在于,示例使用服务器构造函数来启动异步操作。这是有意义的,因为服务器应该一直监听。另一方面,在我的客户机中,我希望首先构造对象,然后拥有一个send()函数,该函数首先连接到端点,然后发送请求,最后侦听回复。这也有道理,不是吗 当我创建我的对象(客户机)时,我使用与服务器示例(winmain.cpp)中相同的方式进行创建。看起来是这样的: client c("www.boost.org); c.start()

我正在基于HTTP服务器上的示例构建一个HTTP客户机。现在,该代码和我的代码之间的区别在于,示例使用服务器构造函数来启动异步操作。这是有意义的,因为服务器应该一直监听。另一方面,在我的客户机中,我希望首先构造对象,然后拥有一个
send()
函数,该函数首先连接到端点,然后发送请求,最后侦听回复。这也有道理,不是吗

当我创建我的对象(客户机)时,我使用与服务器示例(winmain.cpp)中相同的方式进行创建。看起来是这样的:

client c("www.boost.org);
c.start(); // starts the io_service in a thread
c.send(msg_);
守则的有关部分如下:

void enabler::send(common::geomessage& msg_)
{
    new_connection_.reset(new connection(io_service_,
        connection_manager_,
        message_manager_, msg_
    ));

    boost::asio::ip::tcp::resolver resolver(io_service_);
    boost::asio::ip::tcp::resolver::query query(host_address, "http");

    resolver.async_resolve(query, boost::bind(
        &enabler::handle_resolve,
        boost::ref(*this),
        boost::asio::placeholders::error,
        boost::asio::placeholders::iterator
    ));
}

void enabler::run()
{
    io_service_.run();
}
问题是程序在这里的某个地方卡住了。最后打印的是“解析主机”,在该程序结束后。我不知道为什么,因为
io\u服务应该阻塞,直到所有异步操作都返回到它们的回调。但是,如果我改变调用函数的顺序,它就会工作。如果我在调用
async\u resolve()
之后调用
run()
,并且在我的主程序中忽略调用
start()
,它就会工作

在这个场景中,
io_服务
按其应该的方式阻塞,我可以看到我从服务器得到了响应

这与我在调用
async\u resolve()
的同一个类中调用
run()
有关。这是真的吗?当我调用
run()
时,我想我需要从主程序中提供一个引用,是这样的吗

我一直在努力让
io_service::work
正常工作,但是程序卡住了,是的,上面的问题也发生了。所以这并没有真正的帮助


那么,我该怎么做才能把事情做好呢?如前所述,我想要的是能够创建客户机对象,并使
io_服务
始终在客户机类中的一个单独线程中运行。其次,要有一个函数,
send()
,将请求发送到服务器。

在调用
run()
之前,您需要至少开始一些工作,因为它在没有更多工作要做时返回


如果在启动异步解析之前调用它,它将不会有任何工作,因此它将返回。

如果您不希望在任何时候都有一些工作,为了让io_服务保持繁忙,您应该在某个范围内构造一个
io_服务::work
对象,该对象可以退出,而不必先返回
io_服务::run()
。如果您在一个单独的线程中运行
io\u服务
,我想您不会有问题

很难知道你想用这些代码片段做什么。我想你会想做一些类似的事情:

struct client
{
   io_service io_service_;
   io_service::work* w_;
   pthread_t main_thread_;
   client(): w_(new io_service::work(io_service)) { ... }
   void start() { pthread_create(&main_thread_, 0, main_thread, this); }
   static long main_thread(void* arg) { ((client*)arg)->io_service_.run(); }
   // release the io_service and allow run() to return
   void stop() { delete w_; w_ = 0; pthread_join(main_thread_); }
};

谢谢,这至少解释了一些。我可以在async_resolve()之后调用函数send()中的run()。但问题是,如果已经调用了run(),那么再次调用它将是错误的。您可以看到,我想使用send()以便在当前run()完成之前发送请求。有没有办法确定io_服务是否已完成,从而确定再次调用run是否安全?如果这行得通,那就太好了,因为这样我就可以用一个If语句来检查这个。听起来你真正可以使用的是无限期地释放run(),这样你就不用担心了?asio文档有一个。是的!这正是我想要的!但是我已经阅读了你提到的页面,我无法用ioservice::work to work实现这一点。。。我将io_服务定义为客户端类的私有变量。在我的run()函数中,我尝试了以下方法:boost::asio::io_service::work work(io_service);io_服务_uu.run();然后停止我应该调用io_service_u.stop()的整个过程;对吗?因为我只是不能让它工作听起来不错。也许用一些代码来编辑你的问题,这样我就可以看到问题出在哪里了?当然,我会这么做的。但它说我必须等8个小时才能发布我自己问题的答案,因为我是一个新用户。明天我回来的时候会寄的。谢谢