Как работает разрешение имени Boost Asio в Linux?Можно ли использовать NSS? - PullRequest
8 голосов
/ 12 мая 2011

Я пытаюсь заставить мое сетевое приложение работать локально (с сервером и клиентом, работающими на одном компьютере), когда нет сетевого подключения. Кажется, иногда это «просто работает», но в большинстве случаев я получаю:

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

Код, который я сейчас использую:

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

Я уверен, что сузил проблему до ip :: basic_resolver :: resol , но я не могу понять, как это реализовано в Linux или что еще я мог бы использовать , Это , похоже, та же проблема. Кажется, что просто не выполнять поиск и просто использовать 127.0.0.1 должно работать, но когда я попытался заменить строку запроса на

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

это не сработало. Когда я писал это, я обнаружил свою ошибку , флаг address_configured (который установлен по умолчанию) не позволяет возвращать разрешение, если устройство с обратной связью является единственным с адресом. Я до сих пор пишу этот вопрос в надежде, что он кому-то поможет, но я решил свою проблему.

Теперь я использую

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

Хотя другие люди могут не захотеть использовать флаг, который я использую, если они хотят искать имена служб (я просто использую номера портов).

Ответы [ 2 ]

8 голосов
/ 12 мая 2011

Проблема заключалась в том, что конструктор для запроса имеет установленный по умолчанию флаг address_configured, который не возвращает адрес, если устройство с обратной связью является единственным устройством с адресом.Просто установив флаги в 0 или что-то другое, кроме address_configured, проблема исправлена.Вот что я успешно использую сейчас:

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

Надеюсь, что это поможет кому-нибудь с этой проблемой в будущем.

5 голосов
/ 21 января 2014

Конструктор для запроса по умолчанию имеет флаг "address_configured".

IP :: basic_resolver_query :: address_configured

Возвращать адреса IPv4 можно только в том случае, если для системы настроен не зацикленный адрес IPv4. Возвращать адреса IPv6 можно только в том случае, если для системы настроен IP-адрес без обратной связи.

Хотя установка флага на что-то другое будет работать, у него также будут побочные эффекты от указанного флага. Чтобы избежать этого, используйте enum по умолчанию.

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

Раньше можно было просто использовать 0, но библиотека стала более строгой, чтобы предотвратить случайное использование int в качестве имени службы.

...