我正在基于boost website处给出的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
应该阻止,直到所有异步操作都返回到它们的回调。但是,如果我改变了调用函数的顺序,它就可以工作。如果我在调用run()
之后呼叫async_resolve()
并且在我的主程序中省略了start()
,那么它就可以了!
在这种情况下,io_service
会阻止它,我可以看到我从服务器获得响应。
从我调用run()
的同一个类中调用async_resolve()
这一事实可以做些事情。这可能是真的吗?我想当我打电话给run()
时,我需要从主程序中提供一个参考,是这样的吗?
我一直在努力让io_service::work
工作,但程序只是卡住了,是的,类似的问题就像上面发生的那样。所以它并没有真正帮助。
那么,我该怎么做才能做到这一点?正如我之前所说,我想要的是能够创建客户端对象并让io_service
始终在客户端类的单独线程中运行。其次要有一个函数send()
,它将请求发送到服务器。
答案 0 :(得分:2)
在调用run()
之前,您需要至少开始一些工作,因为当没有其他工作要做时它会返回。
如果在启动异步解析之前调用它,它将没有任何工作,因此它会返回。
答案 1 :(得分:0)
如果你不希望一直有一些工作,为了让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_); }
};