2012-06-12 10 views
5

Tengo un reproductor en lata invocando boost::asio::ip::tcp::resolver::resolve() en localhost una vez cada 5 segundos. Cuenta el número de puntos finales devueltos y compara ese valor con la iteración anterior.resultados de Boost.Asio resolver differ

#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); 
    } 
} 

sesión de ejemplo

~> 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 
~> 

Se puede ver que encontró un punto final (127.0.0.1:80) durante aproximadamente 3,5 horas, luego encontró dos (127.0.0.1:80 y [:: 1] : 80). Me pregunto

  1. ¿por qué el conteo de puntos finales cambia de uno a dos?
  2. ¿qué podría causarlo?

Resolviendo las direcciones ipv4 e ipv6 es intencional, no quiero limitar la consulta a solo ipv4. Me doy cuenta de que este comportamiento probablemente no es específico de asio, también tengo un reproductor que invoca directamente al getaddrinfo que muestra el mismo comportamiento. Mi plataforma es ppc64 RHEL 6.2 si eso es relevante. No he intentado reproducir en otro lugar.

+0

La dirección ':: 1' es la dirección del host local IPv6. Tal vez el sistema operativo tarda tanto tiempo en darse cuenta de que tiene habilitado IPv6. –

+0

¿Cuál es el sistema operativo en el que se está ejecutando? – gda2004

+0

@ gda2004 ver la última oración de la pregunta, ppc64 RHEL 6.2 –

Respuesta

3

Puede limitar a resolver sólo con IPv4:
ip tcp :: :: :: resolución de consulta (ip tcp :: :: v4(), el anfitrión, el servicio)

+1

AFAIU la pregunta no es cómo limitar las direcciones devueltas por getaddrinfo, sino por qué aparece la dirección IPv6 después de que ha transcurrido un período de tiempo. – Ralf

+0

Bueno, estaba bajo la impresión de que el iniciador de temas no estaba al tanto del hecho de que su consulta de resolución contenía tanto ipv4 como ipv6, por lo que recibió * consultas de indeseado * ipv6. Por otro lado, es bien sabido que las consultas DNS de ipv6 pueden ser muy lentas ... –

+0

@IgorR. Soy consciente de que la dirección ':: 1' es' ipv6-localhost', he editado mi pregunta para reflejar eso. No quiero limitar mis consultas de resolución solo a ipv4. –

1

Bueno, yo soy un experto impulso , pero una búsqueda rápida me dice que parece estar usando AI_ADDRCONFIG de manera predeterminada (lo cual es bueno, casi siempre debería usarse). Con ese indicador, solo devolverá las direcciones IPv6 si tiene configurada al menos una dirección IPv6 enrutable global. Tal vez su conexión IPv6 no siempre esté disponible?

+0

** Advertencia específica de Windows: ** AI_ADDRCONFIG puede ocasionar que falle la búsqueda de localhost. Consulte [Boost ticket 8503] (https://svn.boost.org/trac/boost/ticket/8503) para obtener más información. –

Cuestiones relacionadas