Я строю HTTP-клиент на основе примера на HTTP-сервере, приведенном по адресу boost website . Теперь разница между этим кодом и моим заключается в том, что в примере используется конструктор сервера для запуска асинхронных операций. Это имеет смысл, поскольку сервер должен постоянно слушать. В моем клиенте, с другой стороны, я хочу сначала создать объект, а затем использовать функцию 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()
, которая отправляет запросы на сервер.