2013-04-18 2 views
0

현재 asio 소켓을 올바르게 재사용하는 방법을 찾으려고합니다. 성공적으로 요청을 보내고 결과를 얻을 수 있습니다. 두 번째로 요청을 보내면 예외가 발생합니다. read_some : 파일 끝입니다. 두 번째 쓰기는 정상적으로 작동하는 것처럼 보입니다. 두 번째 http 요청이 wireshark를 통해 나가는 것을 볼 수 있습니다. 어떤 점에서 연결이 손상되는 소켓에 정보가 남아 있다고 생각합니다. 이 문제로 도움을 주시면 감사하겠습니다. 사용중인 코드는 다음과 같습니다.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; 
} 

편집 : 주요 기능이 추가되었습니다. "연결 유지 연결"헤더 (즉, HTTP 1.0 서버에 유의

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"헤더를 따르지 않습니다. 첫 번째 응답을 받으면 "연결 : 연결 유지"헤더가 보입니까? "HTTP/1.1"을 요청하려고 했습니까? –

답변

3

read_some하려고 할 때이 예외가 사실은 첫 번째 요청이 끝난 후 서버가 무시 즉 HTTP 서버가 연결을 종료한다는 것을 의미 반드시 지속적인 연결을 지원하지는 않음).

그러나 1.1 버전 연결에서는 persistent by default이므로 "HTTP/1.1"을 요청하면이 문제가 해결됩니다.