2011-05-11 17 views
7

Estoy intentando hacer que mi aplicación en red trabaje localmente (con el servidor y el cliente ejecutándose en la misma computadora) cuando no hay conexión de red. Esto parece "sólo trabajo" de vez en cuando, pero la mayoría de las veces terminan con:¿Cómo funciona la resolución del nombre de host de Boost Asio en Linux? ¿Es posible usar NSS?

terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::system::system_error> >' 
     what(): Host not found (authoritative) 
    Aborted 

El código actualmente estoy usando es:

tcp::resolver::query query(host, PORT); 
    tcp::resolver::iterator endpointIterator = resolver.resolve(query); 
    tcp::resolver::iterator end; 

    boost::system::error_code error = boost::asio::error::host_not_found; 
    while(error && endpointIterator != end) 
    { 
    mySocket.close(); 
    mySocket.connect(*endpointIterator++, error); 
    } 
    if(error) 
    throw boost::system::system_error(error); 

Estoy bastante seguro de que he reduzca el problema al ip::basic_resolver::resolve, pero no entiendo cómo se implementa en Linux o qué otra cosa podría querer usar. This parece ser el mismo problema. Parece que no acaba de realizar cualquier consulta de en absoluto y sólo usando 127.0.0.1 debería funcionar, pero cuando traté de reemplazar la línea de consulta con

tcp::resolver::query query(host, PORT, boost::asio::ip::resolver_query_base::address_configured | boost::asio::ip::resolver_query_base::numeric_host 

que aún no ha' trabajo. Mientras escribía esto, encontré mi error, el indicador address_configured (que está configurado por defecto) evita que la resolución regrese si el dispositivo de loopback es el único con una dirección. Todavía estoy publicando esta pregunta con la esperanza de que ayude a otra persona, pero he resuelto mi problema.

Ahora uso

tcp::resolver::query query(host, PORT, boost::asio::ip::resolver_query_base::numeric_service); 

Aunque otras personas que no desee la bandera que estoy usando si ellos quieren para buscar nombres de servicio (sólo estoy usando números de puerto).

Respuesta

8

El problema es que el constructor para la consulta tiene el indicador address_configured establecido de manera predeterminada que no devolverá una dirección si el dispositivo de bucle invertido es el único dispositivo con una dirección. Con solo indicadores de configuración a 0 o cualquier cosa que no sea address_configured, el problema es fijo. Aquí es lo que estoy usando ahora con éxito:

tcp::resolver::query query(host, PORT, boost::asio::ip::resolver_query_base::numeric_service); 

Esperanza esto ayuda a cualquier persona con este problema en el futuro.

4

El constructor para la consulta tiene por defecto el distintivo "address_configured".

ip :: :: basic_resolver_query address_configured

sólo devuelven direcciones IPv4 si una dirección IPv4 sin bucle de retorno está configurado para el sistema. Solo devuelva direcciones IPv6 si una dirección IPv6 sin bucle de retorno está configurada para el sistema.

Si bien el ajuste de la bandera a otra cosa funcionará, también tendrá los efectos secundarios de dicha bandera. Para evitar esto, use el "predeterminado" de la enumeración.

tcp::resolver::query query(host, PORT, boost::asio::ip::resolver_query_base::flags()); 

lo que solía ser posible utilizar sólo 0, pero la biblioteca se ha vuelto más estricta para evitar el uso accidental de un int como el nombre del servicio.

Cuestiones relacionadas