2013-09-29 5 views
0

저는 boost :: asio에서 초보자이며 첫 번째 문제가 있습니다. 간단한 호스트 확인자를 만듭니다 (아래 전체 코드 참조).boost :: asio :: io_service 소멸자가 매우 오래 실행됩니다.

문제 1. 인터넷 연결이 끊어진 경우 호스트 확인자가 처음으로 deadline_timer를 입력 한 후 해결을 중지합니다. "localhost"는 언제든지 해결해야한다는 가정하에. 그러나 "localhost"는 google.us를 해결하는 동안 시간 초과 후 해결되지 않습니다 (예 : 이더넷 잭이 연결되지 않음). 존재하지 않는 TLD (예 : google.usd 대신 google.us)를 해결할 때와 동일한 동작입니다.

문제 2. 인터넷 연결이 끊어진 경우 소멸자 io_service가 매우 오래 실행됩니다 (일반적으로 5 초).

무엇이 잘못 되었나요? 내가 VS2012를 사용

에서 돌아온 후 1.54

파일 hostresolver.h

pragma once 

#include <set> 

#include <boost/system/error_code.hpp> 
#include <boost/asio.hpp> 
#include <boost/asio/ip/basic_resolver.hpp> 
#include <boost/asio/ip/basic_resolver_iterator.hpp> 

typedef std::set<unsigned long> hostresolver_result_container; 

class hostresolver 
{ 
public: 
    hostresolver(boost::asio::io_service* io_service); 
    ~hostresolver(void); 

    boost::asio::io_service* ios_ptr; 
    boost::asio::ip::tcp::resolver resolver_; 
    boost::asio::deadline_timer timer_; 

    volatile bool is_completed; 
    bool is_timeout; 
    std::string hostname; 
    hostresolver_result_container result; 

    void on_timeout(const boost::system::error_code &err); 
    void start_resolve(const char* hostname, int timeout_seconds); 
    void finish_resolve(const boost::system::error_code& err, boost::asio::ip::tcp::resolver::iterator endpoint_iterator); 

private: 
    void stop(); 
}; 

파일 hostresolver.cpp

#include "stdafx.h" 
#include "hostresolver.h" 

#include <boost/bind.hpp> 

hostresolver::hostresolver(boost::asio::io_service* io_service) : 
    resolver_(*io_service), timer_(*io_service), is_completed(false), is_timeout(false) 
{ 
    ios_ptr = io_service; 
} 

hostresolver::~hostresolver(void) 
{ 
} 

void hostresolver::start_resolve(const char* hostname, int timeout_second) 
{ 
    this->hostname.assign(hostname); 

    timer_.expires_from_now(boost::posix_time::seconds(timeout_second)); 
    timer_.async_wait(boost::bind(&hostresolver::on_timeout, this, _1)); 

    boost::asio::ip::tcp::resolver::query query(hostname, "http"); 
    resolver_.async_resolve(query, 
          boost::bind(&hostresolver::finish_resolve, this, 
          boost::asio::placeholders::error, 
          boost::asio::placeholders::iterator)); 

    do 
    { 
     ios_ptr->run_one(); 
    } 
    while (!is_completed); 
} 

void hostresolver::stop() 
{ 
    resolver_.cancel(); 
    timer_.cancel(); 
    is_completed = true; 
} 

void hostresolver::on_timeout(const boost::system::error_code &err) 
{ 
    if ((!err) && (err != boost::asio::error::operation_aborted)) 
    { 
     is_timeout = true; 
     stop(); 
    } 
} 

void hostresolver::finish_resolve(const boost::system::error_code& err, boost::asio::ip::tcp::resolver::iterator endpoint_iterator) 
{ 
    if (!err) 
    { 
     while (endpoint_iterator != boost::asio::ip::tcp::resolver::iterator()) 
     { 
      boost::asio::ip::tcp::endpoint endpoint = *endpoint_iterator; 
      if (endpoint.address().is_v4()) 
      { 
       result.insert(endpoint.address().to_v4().to_ulong()); 
      } 
      endpoint_iterator++; 
     } 
    } 

    stop(); 
} 

파일 MAIN.CPP

#include "stdafx.h" 

#include "hostresolver.h" 


int _tmain(int argc, _TCHAR* argv[]) 
{ 
    boost::asio::io_service ios; 

    for (int i = 0; i < 2; i++) 
    { 
     std::cout << "iteration: " << i << std::endl; 

     { 
      hostresolver hres(&ios); 
      hres.start_resolve("localhost", 1); 
      if (hres.result.size() == 0) 
       std::cout << "failed" << std::endl; 
     } 

     { 
      hostresolver hres(&ios); 
      hres.start_resolve("google.usd", 1); 
     } 
    } 


    return 0; 
} 

답변

0

을 향상 run_once의 경우 io_service은 "중지됨"상태를 유지할 가능성이 큽니다. 따라서 run_once()에 다시 전화하기 전에 ios_ptr->reset()으로 전화해야합니다. run_once 기준에서 인용 :

Return Value: The number of handlers that were executed. A zero return value implies that the io_service object is stopped (the stopped() function returns true). Subsequent calls to run(), run_one(), poll() or poll_one() will return immediately unless there is a prior call to reset().

+0

io_service :: 재설정하기 전에 호출해야하는 초 이상 실행의 호출(), run_one(), 여론 조사() 또는 poll_one 세트() . – user1215838

+0

@ user1215838 "... io_service가 중지되거나 작업이 부족하여 이러한 함수가 이전에 호출 된 경우" –

관련 문제