Нужно ли мне перебирать getaddrinfo()?

Для этого есть похожие вопросы, но я не могу найти ответ, который я ищу.

#include <netdb.h>

int getaddrinfo (const char *hostname, 
                 const char *service, 
                 const struct addrinfo *hints, 
                 struct addrinfo **result) ;

Returns: 0 if OK, nonzero on error 

Что мне интересно, так это то, почему нам нужна итерация по связанному списку, на который указывает result, даже если мы определяем hints вместо NULL. Мы уже знаем IP(имя хоста) и PORT(сервис). Не так ли?

Если повторение необходимо, не могли бы вы привести пример, просто рассмотрев парня, не обладающего полным знанием сети?

Например, я определяю hints следующим образом.

struct addrinfo  hints;

        memset(&hints, 0, sizeof hints);
        hints.ai_family = AF_UNSPEC;        /* IPv4 or IPv6 */
        hints.ai_socktype = SOCK_STREAM;    /* TCP */
        hints.ai_flags = 0;
        hints.ai_protocol = 0;

person snr    schedule 13.05.2019    source источник
comment
AF_UNSPEC означает, что вы можете получить как минимум два результата; один для IPv4 и один для IPv6. Кроме того, каждый интерфейс может иметь более одного IP-адреса (несколько записей A), тогда вы сможете получить еще больше записей.   -  person jww    schedule 13.05.2019
comment
Вы можете избежать повторения, если вас устраивает первый результат, но вы не должны пренебрегать проверкой этого результата, прежде чем принять его.   -  person John Bollinger    schedule 13.05.2019
comment
@jww для последнего случая, предполагаем ли мы, что параметр hostname является буквенным именем (например, google.com) вместо числового IP-адреса? Например, на терминале dig A www.google.com дает одну запись A, а yahoo.com — 6 записей A. Но давайте предположим, что мы уже передали числовой IP-адрес вместо алфавитного (например, yahoo.com) в функцию getaddr(), разве она не ограничивается IP-адресом? Я до сих пор не понимаю, зачем повторять это для примера. Или нам вообще нужна итерация для этого примера?   -  person snr    schedule 14.05.2019
comment
@snr, если у тебя уже был числовой адрес, то зачем тебе звонить getaddrinfo? Это интерфейс разрешения имен.   -  person John Bollinger    schedule 14.05.2019
comment
@John Bollingerr, сэр, разве эта функция не предназначена для обоих видов использования? имя и номер. Более того, Керриск говорит, что это современный подход к сокетам. ??   -  person snr    schedule 14.05.2019
comment
@snr, вполне вероятно, что вы можете получить полезный результат, подав числовой адрес в getaddrinfo(), но если вы заранее знаете, что адрес является числовым, то более эффективно избегать использования библиотеки распознавателя. А если заранее не знать, то вопрос спорный, потому что потом нельзя различить отдельные числовые и нечисловые падежи.   -  person John Bollinger    schedule 14.05.2019
comment
@JohnBollinger, даже если вы уже знаете IP, функция все равно полезна для разбора IP и подготовки для вас необходимой структуры sockaddr.   -  person Remy Lebeau    schedule 14.05.2019


Ответы (1)


В старые времена, до того, как IPv6 стал вещью, вы могли предположить, что имя хоста может быть разумно разрешено к одному IP-адресу.

В настоящее время это просто не так, getaddrinfo возвращает адреса как ipv4, так и ipv6, и вам действительно нужно попробовать оба из них. Если вы уверены, что ваши пользователи будут в хороших сетях или ваши пользователи могут терпеть длительные задержки, может быть достаточно попробовать «подключиться» к ним последовательно, но если вам нужно быстро установить соединения в потенциально сломанных сетях, тогда может оказаться необходимым реализовать более сложный процесс (поиск «счастливых глазных яблок»).

person plugwash    schedule 13.05.2019