У меня возникла проблема при создании клиентской программы, отправляющей запросы. В запросе используются поддерживаемые HTTP-соединения HTTP. Когда соединение закрыто (из-за таймаута или максимального удара), я пытаюсь запустить новое соединение, если оно не доступно, и отправить запрос. Соединение работает отлично однако, когда я пытаюсь отправить письмо, ничего не отправляется (согласно Wireshark), но мой код ошибки для записи был успешным. Получающий сервер также не получает никакой информации. Вот основные части моего кода:asio write successing, но информация не отправлена
void request_handler::send_1(std::vector<std::string> *bid_vector, std::string request_path, boost::mutex *bids_mutex)
{
try
{
boost::asio::streambuf request;
std::ostream request_stream(&request);
std::string reply_information;
request_stream << "GET /tests HTTP/1.1\r\n";
request_stream << "Host: 10.1.10.160\r\n";
request_stream << "Accept: */*\r\n";
request_stream << "Connection: keep-alive\r\n\r\n";
server1_mutex_.lock();
if(server1_available_map_.size() == 0)
{
server1_mutex_.unlock();
persistent_connection *new_connection = new persistent_connection("10.1.10.160","80");
if(new_connection->send(request, reply_information))
{
server1_mutex_.lock();
server1_available_map_[new_connection->get_id()] = new_connection;
server1_mutex_.unlock();
}
}
else
{
persistent_connection *current_connection = (*(server1_available_map_.begin())).second;
server1_available_map_.erase(current_connection->get_id());
server1_mutex_.unlock();
int retry_counter = 20;
while(!current_connection->query_rtb(request, reply_information) && --retry_counter != 0)
{
delete current_connection;
server1_mutex_.lock();
if(server1_available_map_.size() == 0)
{
server1_mutex_.unlock();
current_connection = new persistent_connection("10.1.10.160","80");
}
else
{
current_connection = (*(server1_available_map_.begin())).second;
server1_available_map_.erase(current_connection->get_id());
server1_mutex_.unlock();
}
}
//Could not connect to 20 connections
if(retry_counter == 0)
{
Log::fatal("Could not connect in 20 tries");
delete current_connection;
return;
}
server1_mutex_.lock();
server1_available_map_[current_connection->get_id()] = current_connection;
server1_mutex_.unlock();
}
bids_mutex->lock();
bid_vector->push_back(reply_information);
bids_mutex->unlock();
}
catch(boost::thread_interrupted& e)
{
std::cout << "before cancel 1" << std::endl;
return;
}
catch(...)
{
std::cout << "blah blah blah" << std::endl;
}
}
И мой persistent_connection класс
persistent_connection::persistent_connection(std::string ip, std::string port):
io_service_(), socket_(io_service_), host_ip_(ip)
{
boost::uuids::uuid uuid = boost::uuids::random_generator()();
id_ = boost::lexical_cast<std::string>(uuid);
boost::asio::ip::tcp::resolver resolver(io_service_);
boost::asio::ip::tcp::resolver::query query(host_ip_,port);
boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query);
boost::asio::ip::tcp::endpoint endpoint = *iterator;
socket_.async_connect(endpoint, boost::bind(&persistent_connection::handler_connect, this, boost::asio::placeholders::error, iterator));
io_service_.run();
}
void persistent_connection::handler_connect(const boost::system::error_code &ec, boost::asio::ip::tcp::resolver::iterator endpoint_iterator)
{
if(ec)
{
std::cout << "Couldn't connect" << ec << std::endl;
return;
}
else
{
boost::asio::socket_base::keep_alive keep_option(true);
socket_.set_option(keep_option);
std::cout << "Connect handler" << std::endl;
}
}
bool persistent_connection::send(boost::asio::streambuf &request_information, std::string &reply_information)
{
std::cout << "DOING QUERY in " << id_ << std::endl;
boost::system::error_code write_ec, read_ec;
try
{
std::cout << "Before write" << std::endl;
boost::asio::write(socket_, request_information, write_ec);
std::cout << write_ec.message() << std::endl;
}catch(std::exception& e)
{
std::cout << "Write exception: " << e.what() << std::endl;
}
if(write_ec)
{
std::cout <<"Write error: " << write_ec.message() << std::endl;
return false;
}
boost::array<char,8192> buf;
buf.assign(0);
try
{
std::cout << "Before read" << std::endl;
boost::asio::read(socket_, boost::asio::buffer(buf), boost::asio::transfer_at_least(1), read_ec);
std::cout << read_ec.message() << std::endl;
}catch(std::exception& e)
{
std::cout << "Read exception: " << e.what() << std::endl;
}
if(read_ec)
{
std::cout << "Read error: " << read_ec.message() << std::endl;
return false;
}
reply_information = buf.data();
return true;
}
std::string persistent_connection::get_id()
{
return id_;
}
Путь для того чтобы это произошло, если server1_available_map_.size()> 0, и если в то время как выполняется, и выходит из строя. И тогда, если размер == 0 на втором сервере1_available_map_.size();
Выход для вызова:
DOING QUERY in 69a8f0ab-2a06-45b4-be26-37aea6d93ff2
Before write
Success
Before read
End of file
Read error: End of file
Connect handler
DOING QUERY in 4eacaa96-1040-4878-8bf5-c29b87fa1232
Before write
Success
Before read
Это показывает, что первое соединение получает конец файла (соединение закрыто сервером на другом конце). Второе соединение соединяет тонкое (сообщение обработчика Connect), и запрос выполняется во втором соединении (другой идентификатор), и запись, по-видимому, успешна, и программа зависает при чтении (потому что читать нечего).
Есть ли у кого-нибудь идеи, почему это происходит? Я что-то делаю неправильно?
Спасибо
Огромное вам спасибо, это было именно так, не знал, что чтение из streambuf было разрушительным. – Eumcoz