使用boost::asio时的参考问题(我猜)

Reference problem (I guess) when using boost::asio

本文关键字:问题 我猜 参考 boost asio 使用      更新时间:2023-10-16

我正在根据boost网站上给出的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_service应该阻止,直到所有异步操作都返回到它们的回调。但是,如果我更改调用函数的顺序,它就会起作用。如果我在调用async_resolve()后立即调用run()并且在我的主程序中省略调用start(),它就可以工作了!

在这种情况下,io_service块,我可以看到我从服务器得到响应。

这与我从与我打电话async_resolve()相同的班级内部调用run()这一事实有关。这是真的吗?我想当我调用run()时,我需要从主程序给出一个参考,是这样的吗?

我一直在努力让io_service::work工作,但程序只是卡住了,是的,发生了与上述类似的问题。所以它并没有真正的帮助。

那么,我该怎么做才能做到这一点呢?正如我之前所说,我想要的是能够创建客户端对象,并使io_service始终在客户端类内的单独线程中运行。其次,要有一个函数,send() ,将请求发送到服务器。

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

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

如果您不希望始终有一些工作,为了保持io_service忙碌,您应该在某个范围内构造一个 io_service::work 对象,该对象可以退出而无需io_service::run()先返回。如果您在单独的线程中运行io_service,我想您不会有问题。

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

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_); }
};