我正在根據HTTP服務器上的示例構建一個HTTP客戶端,在boost website處給出。現在,該代碼和我的區別在於,該示例使用服務器構造函數來啓動異步操作。這是有道理的,因爲服務器應該一直聽。另一方面,在我的客戶端中,我想先構造對象,然後有一個send()
函數,該函數從連接到端點開始,然後發送請求並最終收聽答覆。這也有道理,不是嗎?使用boost :: asio時出現的參考問題(我猜)
當我創建我的對象(客戶端)時,我以與服務器示例(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
塊,因爲它應該,我可以看到,我從服務器得到響應。
這與我從同一班級呼叫run()
這一事實有關,因爲我呼叫async_resolve()
。這是真的嗎?我想當我打電話給run()
時,我需要從主程序中提供一個參考,是這樣嗎?
我一直在努力獲得io_service::work
工作,但程序只是卡住了,是的,類似的問題,發生上述情況。所以它並沒有真正的幫助。
那麼,我能做些什麼才能做到這一點?正如我前面所說的,我想要的是能夠創建客戶端對象,並讓io_service
始終在客戶端類中的單獨線程中運行。其次有一個功能,send()
,發送請求到服務器。
謝謝,至少解釋了一些。我可以在async_resolve()之後的函數send()中調用run()。但問題是,如果run()已被調用,則再次調用它將是錯誤的。您看到我想使用send(),以便在當前運行()完成之前發送請求。有沒有辦法確定io_service是否已完成,從而確定再次調用run是否安全?如果這能起作用,那將是好事,因爲那樣我就可以有一個if語句來檢查它。 – 2011-05-12 18:12:46
這聽起來像你真的可以使用的是讓run()無限期地走,所以你不必擔心它? asio文檔有一個[部分只是爲此](http://www.boost.org/doc/libs/1_46_1/doc/html/boost_asio/reference/io_service.html#boost_asio.reference.io_service.stopping_the_io_service_from_running_out_of_work)。 – 2011-05-12 18:39:00
是的!那正是我想要的!但是我已經閱讀過你提到的那個頁面,而且我不能用ioservice :: work來獲取這個東西......我有一個定義爲客戶類的私有變量的io_service。在我的run()函數中,我試過這個: boost :: asio :: io_service :: work work(io_service_); io_service_.run(); 然後停止整個事情我應該調用io_service_.stop();那是對的嗎?因爲我可以'讓它起作用 – 2011-05-12 18:48:07