#c #sockets #boost-asio
#c #сокеты #boost-asio
Вопрос:
Я пытаюсь написать программу, которая будет запрашивать определенные фрагменты информации, например, внутреннюю температуру, с камеры, которая действует как сервер, извините, если моя терминология отключена, но в основном я имею в виду, что связь с камерой достигается с помощью HTTP get запросов. Программа, по сути, просто вызывает слегка адаптированную версию async_client из библиотеки boost, каждый раз передавая другой путь для проверки другого значения, затем сравнивает возвращаемое значение, чтобы убедиться, что оно звучит разумно, прежде чем передавать другой путь для проверки чего-то еще.
Кажется, что код работает правильно с первого раза, но со второй попытки он переходит к функции handle_connect и выдает «Ошибка: запрос на подключение был выполнен в уже подключенном сокете»
Вот как выглядит функция:
void Async_client::handle_connect(const boost::system::error_codeamp; err, tcp::resolver::iterator endpoint_iterator)
{
http_deadline_timer_.cancel();
if (!err)
{
// The connection was successful. Send the request.
boost::asio::async_write(socket_, request_, boost::bind(amp;Async_client::handle_write_request, this,
boost::asio::placeholders::error));
//deadline timer stuff
http_deadline_timer_.expires_from_now( ::boost::posix_time::seconds(1));
http_deadline_timer_.async_wait( ::boost::bind(amp;Async_client::call_handle_deadline_timeout, this, boost::asio::placeholders::error));
}
else if (endpoint_iterator != tcp::resolver::iterator())
{
// The connection failed. Try the next endpoint in the list.
socket_.close();
tcp::endpoint endpoint = *endpoint_iterator;
socket_.async_connect(endpoint, boost::bind(amp;Async_client::handle_connect, this,
boost::asio::placeholders::error, endpoint_iterator));
//deadline timer stuff
http_deadline_timer_.expires_from_now( ::boost::posix_time::seconds(1));
http_deadline_timer_.async_wait( ::boost::bind(amp;Async_client::call_handle_deadline_timeout, this, boost::asio::placeholders::error));
}
else
{
LOG_WARN("Async_client.cpp: Error: " << err.message());
}
}
Я попытался скопировать этот раздел кода из оператора else if в оператор else, думая, что он закроет сокет и повторно запустит функцию handle_connect, но, похоже, это просто сбой программного обеспечения в строке endpoint= * endpoint_iterator .
socket_.close();
tcp::endpoint endpoint = *endpoint_iterator;
socket_.async_connect(endpoint, boost::bind(amp;Async_client::handle_connect, this,
boost::asio::placeholders::error, endpoint_iterator));
У кого-нибудь есть идеи, что я должен делать в этой ситуации? Отключите сокет и снова подключитесь? Если да, то как мне это сделать?
Комментарии:
1. В начале первой функции я добавил socket_.close(); для закрытия сокета каждый раз, когда используется async_client . К счастью, это, похоже, ничего не нарушило при первом вызове async_client, и при втором запуске он, похоже, позволил ему пройти мимо функции handle_connect, однако он доходит только до handle_read_status_line, где он считывает response_stream как 0, что является недопустимым ответом, при первом запускев программе response_stream был 0x23f350. Связаны ли эти проблемы? Есть идеи, что я могу с этим поделать?
2. Думаю, мне удалось устранить проблему, добавив «response_.consume(response_.size());» в начале первой функции сразу после строки socket_.close(); . Это очищает ответ очистки, который является boost::asio::streambuf . @Sam Miller: что вы отредактировали в моем сообщении? Я думаю, это не имеет большого значения, но если я сделал что-то не так в том, как я задал свой вопрос, было бы хорошо знать в следующий раз. Спасибо.
3. @meerkat посмотрите журнал изменений. Я удалил вашу прощальную речь и добавил тег boost-asio. Если вы решили свой вопрос, пожалуйста, добавьте ответ.
Ответ №1:
Возможно, использование SO_REUSEADDR
опции with setsockopt
могло бы помочь.