2012-06-12 16 views
5

Mam reproduktora w puszkach, który wywołuje boost::asio::ip::tcp::resolver::resolve() na localhost raz na 5 sekund. Zlicza liczbę zwróconych punktów końcowych i porównuje tę wartość z poprzednią iteracją.wyniki z Boost.Asio resolver różnią się

#include <boost/asio.hpp> 

#include <iostream> 

int main(int argc, char *argv[]) 
{ 
    if (argc < 3) { 
     std::cerr << argv[0] << " host port" << std::endl; 
     exit(EXIT_FAILURE); 
    } 
    const char* host = argv[1]; 
    const char* service = argv[2]; 

    boost::asio::io_service io_service; 
    boost::asio::ip::tcp::resolver resolver(io_service); 

    size_t previous = 0; 
    while (true) { 
     boost::asio::ip::tcp::resolver::iterator i(
       resolver.resolve(
        boost::asio::ip::tcp::resolver::query(host, service) 
        ) 
       ); 
     size_t count(0); 
     while (i != boost::asio::ip::tcp::resolver::iterator()) { 
      std::cout << i->endpoint() << std::endl; 
      ++i; 
      ++count; 
     } 

     std::cout << "got " << count << " addresses" << std::endl; 
     if (previous == 0) { 
      previous = count; 
     } 
     assert(count == previous); 

     sleep(5); 
    } 
} 

sesja próbka

~> time ./addrinfo_asio localhost 80 

... 

127.0.0.1:80 
got 1 addresses 
[::1]:80 
127.0.0.1:80 
got 2 addresses 
addrinfo_asio: addrinfo_asio.cc:35: int main(int, char**): Assertion `count == previous' failed. 
Aborted (core dumped) 

real 216m20.515s 
user 0m0.181s 
sys  0m0.193s 
~> 

Widać to znaleźć jeden punkt końcowy (127.0.0.1:80) przez około 3,5 godziny, po czym znaleziono dwie (127.0.0.1:80 i [:: 1] : 80). Zastanawiam się,

  1. dlaczego liczba punktów końcowych zmienia się z jednego na dwa?
  2. co może spowodować?

Rozwiązywanie adresów IP i IPv6 jest celowe, nie chcę ograniczać zapytania do samego adresu IPv4. Rozumiem, że to zachowanie prawdopodobnie nie jest specyficzne dla asio, mam też reproduktora, który bezpośrednio wywołuje takie samo zachowanie. Moja platforma to ppc64 RHEL 6.2, jeśli jest to istotne. Nie próbowałem reprodukować gdzie indziej.

+0

Adres ':: 1' to adres localhost IPv6. Może system operacyjny potrzebuje tak dużo czasu, aby mieć włączony IPv6? –

+0

jaki jest system operacyjny? – gda2004

+0

@ gda2004 zobacz ostatnie zdanie pytania, PPC64 RHEL 6.2 –

Odpowiedz

3

można ograniczyć tylko do rozpoznawania nazw dla protokołu IPv4:
ip :: tcp :: rezolwer :: query (ip :: tcp :: v4(), host, serwis)

+1

AFAIU pytanie nie polega na ograniczaniu adresów zwracanych przez getaddrinfo, ale dlaczego adres IPv6 pojawia się po pewnym okresie czasu. – Ralf

+0

Cóż, byłem pod wrażeniem, że rozrusznik tematu był nieświadomy faktu, że jego zapytanie o resolver zawierało zarówno ipv4, jak i ipv6, więc otrzymał * niepożądane * zapytania ipv6. Z drugiej strony dobrze wiadomo, że zapytania DNS dla ipv6 mogą być boleśnie powolne ... –

+0

@IgorR. Zdaję sobie sprawę, że adres ':: 1' to' ipv6-localhost', zredagowałem moje pytanie, aby to odzwierciedlić. Nie chcę ograniczać moich zapytań dotyczących rozwiązań tylko do ipv4. –

1

Dobrze, że nie jestem ekspertem doładowania , ale szybkie przeglądanie mówi mi, że domyślnie używa domyślnie AI_ADDRCONFIG (co jest dobre, powinno być prawie zawsze używane). Z tą flagą zwróci ona tylko adresy IPv6, jeśli skonfigurowany jest co najmniej jeden globalny routowany adres IPv6. Być może twoje połączenie IPv6 nie zawsze jest dostępne?

+0

** Ostrzeżenie specyficzne dla systemu Windows: ** AI_ADDRCONFIG może powodować niepowodzenia wyszukiwania localhost. Aby uzyskać szczegółowe informacje, patrz [Boost ticket 8503] (https://svn.boost.org/trac/boost/ticket/8503). –

Powiązane problemy