2013-04-18 3 views
0

В настоящее время я пытаюсь выяснить, как правильно повторно использовать разъем asio. Я могу успешно отправить запрос и получить результат. Во второй раз, когда я отправляю запрос, я получаю исключение: read_some: Конец файла. Вторая запись, кажется, работает нормально, я вижу второй запрос http, выходящий на wirehark. Я думаю, что информация о сокете осталась в сокете, которая каким-то образом искажает мое соединение. Любая помощь будет оценена с этой проблемой. Вот код, который я использую:Повторное использование соединения ASIO, исключение read_some

persistent_connection::persistent_connection(std::string ip, std::string port): 
io_service_(), socket_(io_service_), is_setup_(false) 
{ 
    boost::asio::ip::tcp::resolver resolver(io_service_); 
    boost::asio::ip::tcp::resolver::query query(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); 
    } 
} 


void persistent_connection::write(std::string message) 
{ 
    std::string request_stream = "GET /" + message + " HTTP/1.0\r\n"; 
    request_stream += "HOST: 10.1.10.220"; 
    request_stream += "Accept: */*\r\n"; 
    request_stream += "Connection: keep-alive\r\n\r\n"; 

    try 
    { 
     boost::asio::write(socket_, boost::asio::buffer(request_stream, request_stream.size())); 
    }catch(std::exception& e) 
    { 
     std::cout << "Write exception: " << e.what() << std::endl; 
    } 

    boost::array<char,8192> buf; 
    try 
    { 
     socket_.read_some(boost::asio::buffer(buf)); 
    }catch(std::exception& e) 
    { 
     std::cout << "Read exception: " << e.what() << std::endl; 
    } 

    std::string response = buf.data(); 
    std::cout << response << std::endl; 
} 

Редактировать: добавлена ​​основная функция.

int main() 
{ 
    persistent_connection p("10.1.10.220", "80"); 
    std::string check; 
    do 
    { 
     std::cin >> check; 
     if(check.compare("s") == 0) 
     { 
      std::cout << "Sending" << std::endl; 
      p.write("100"); 
     } 
    }while(check.compare("x") != 0); 
} 
+0

Не совсем понятно, как вы используете приведенный выше код. Где заканчивается «первый раз» и где начинается «второй раз»? Вы уверены, что сверстник не закрывает соединение после первого раза? –

+0

Извините, оставил эту часть. В основном первый раз пишется, все работает нормально. В следующий раз, когда я попытаюсь использовать запись, я получаю исключение для чтения. – Eumcoz

+1

Это означает, что http-сервер закрывает соединение после завершения первого запроса, то есть он не соблюдает заголовок «Connection: keep-alive». Когда вы получите первый ответ, вы видите заголовок «Connection: keep-alive»? Вы пытались запросить «HTTP/1.1»? –

ответ

3

Тот факт, вы получите это исключение при попытке read_some означает, что сервер HTTP закрывает соединение после первого запроса закончена, то есть сервер игнорирует «Connection: Keep-живой» заголовок (обратите внимание, что HTTP 1.0 серверов не обязательно поддерживают постоянные соединения).

Однако в версиях версии 1.1 есть persistent by default, поэтому запрос «HTTP/1.1» должен решить эту проблему.

Смежные вопросы