Длинные последовательности чисел являются отлично подходящим методом идентификации для компьютеров, позволяющим им однозначно узнавать друг друга. Однако большинство людей охватывает ужас при мысли о том, что придется иметь дело с большим количеством цифр. Для того чтобы разрешить людям применять текстовые названия для компьютеров вместо числовых, в состав протоколов TCP/IP входит распределенная
база данных для взаимных преобразований имен хостов и IP-адресов. Эта база данных называется DNS (Domain Name System — служба имен доменов), она подробно рассматривается в [34] и [1].
Служба DNS предлагает много функций, но сейчас нас интересует одна — возможность преобразования IP-адресов в имена хостов и наоборот. Несмотря на то что это преобразование должно выполняться как однозначное соответствие, на самом деле оно представляет собой отношение типа "многие ко многим". Другими словами, каждый IP-адрес может соответствовать нулю или более именам хостов, а каждое имя хоста соответствует нулю или более IP-адресам.
Использование неоднозначного соответствия между именами хостов и IP-адресами может показаться странным. Однако многие Internet-сайты применяют одну и ту же машину для ftp-сайта и Web-сайта. При этом адреса
www.some.org
и
ftp.some.org
должны ссылаться на одну и ту же машину, а для одной машины не нужны два IP-адреса. Таким образом, два имени хостов сводятся к одному IP-адресу. Каждый IP-адрес имеет одно первичное, или каноническое имя хоста, которое используется, если IP-адрес требуется преобразовать в единственное имя хоста во время обратного поиска имен.
Наиболее распространенной причиной, по которой одному имени хоста ставится в соответствие несколько IP-адресов, является балансировка нагрузки. Серверы имен (программы, предлагающие преобразование имен хостов в IP-адреса) часто конфигурируются так, что возвращают в разное время разные адреса для одного и того же имени. Это позволяет нескольким физическим машинам поддерживать единую службу.
Появление IPv6 повлекло за собой еще одну причину, по которой одно имя хоста должно иметь несколько адресов. Многие машины сейчас имеют одновременно и IPv4-, и IPv6-адреса.
Библиотечная функция
getaddrinfo
[134] предлагает программам простой доступ к преобразованиям имен хостов DNS.
#include <sys/types.h>
#include <socket.h>
#include <netdb.h>
int getaddrinfo(const char * hostname, const char * servicename,
Концепция этой функции достаточно простая, однако весьма мощная, в связи с этим ее описание может показаться несколько запутанным. Идея заключается в том, что функция принимает имя хоста, имя службы (или оба из них) и превращает их в список IP-адресов. Затем с использованием
hints
список фильтруется и те адреса, которые не нужны приложению, отбрасываются. Окончательный список возвращается в виде связного списка в переменной
res
.
134
Если у вас большой опыт в программировании сокетов (или вы сравниваете данную книгу с ее первым изданием), то вы обязательно заметите, что функции, применявшиеся для преобразования имен, значительно изменились. Эти изменения позволяют создавать программы абсолютно независимо от того протокола, который они используют. Теперь гораздо легче разрабатывать программы, работающие как на IPv4-, так и на IPv6-машинах. Они также должны распространяться на остальные протоколы, хотя функция
getaddrinfo
в данный момент работает только для IPv4 и IPv6.
Искомое имя хоста содержится в первом параметре и может равняться
NULL
, если производится поиск только службы. Параметр
hostname
может быть именем (например,
www.ladweb.net
) или IP-адресом (с точками или двоеточиями в качестве разделителей), который функция
getaddrinfo
преобразует в двоичный адрес.
Второй параметр
servicename
указывает имя той службы, для которой нужно извлечь официальный порт. Если он равен