solaris % hostent cnn.com
official hostname: cnn.com
address: 64.236.16.20
address: 64.236.16.52
address: 64.236 16.84
address: 64.236.16.116
address: 64.236.24.4
address: 64.236.24.12
address: 64.236.24.20
address: 64.236.24.28
Далее идет имя, представленное в разделе 11.2 как имя с записью типа CNAME:
solaris % hostent www
official hostname: linux.unpbook.com
alias: www.unpbook.com
address: 206.168.112.219
Как мы и предполагали, официальное имя узла отличается от нашего аргумента командной строки.
Чтобы увидеть строки ошибок, возвращаемые функцией hstrerror
, мы сначала задаем несуществующее имя узла, а затем имя, имеющее только запись типа MX:
solaris % hostent nosuchname.invalid
gethostbyname error for host: nosuchname.invalid: Unknown host
solaris % hostent uunet.uu.net
gethostbyname error for host: uunet.uu.net: No address associated with name
11.4 Функция gethostbyaddr
Функция gethostbyaddr
получает в качестве аргумента двоичный IP-адрес и пытается найти имя узла, соответствующее этому адресу. Ее действие обратно действию функции gethostbyname
.
#include
struct hostent *gethostbyaddr(const char * addr , size_t len , int family );
Возвращает: непустой указатель в случае успешного выполнения, -1 в случае ошибки
Эта функция возвращает указатель на ту же структуру hostent
, которую мы описывали при рассмотрении функции gethostbyname
. Обычно в этой структуре нас интересует поле h_name
, каноническое имя узла.
Аргумент addr
не относится к типу char*
, но в действительности это указатель на структуру in_addr
, содержащую адрес IPv4. Поле len
— это длина структуры: 4 для адресов IPv4. Аргумент family
будет иметь значение AF_INET
.
В терминах DNS функция gethostbyaddr
запрашивает у сервера имен запись типа PTR в домене in-addr.arpa
.
11.5. Функции getservbyname и getservbyport
Службы, как и узлы, также часто идентифицируются по именам. Используя в нашем коде имя службы вместо номера порта, при условии, что имена служб сопоставляются номерам портов в некотором файле (обычно /etc/services
), мы получаем следующее преимущество. Если этой службе будет назначен другой номер порта, то нам будет достаточно изменить одну строку в файле /etc/services
, вместо того чтобы перекомпилировать все приложения. Следующая функция, getservbyname
, ищет службу по ее заданному имени.
ПРИМЕЧАНИЕ
Канонический список номеров портов, назначенных определенным службам, поддерживается IANA и располагается по адресу http://www.iana.org/assignments/port-numbers (см. раздел 2.9). Файл /etc/services чаще всего содержит некоторое подмножество списка IANA.
#include
struct servent *getservbyname(const char * servname , const char * protoname );
Возвращает: непустой указатель в случае успешного выполнения, NULL в случае ошибки
Функция возвращает указатель на следующую структуру:
struct servent {
char *s_name; /* официальное имя службы */
char **s_aliases; /* список псевдонимов */
int s_port; /* номер порта, записанный в сетевом порядке байтов */
char *s_proto; /* протокол, который нужно использовать */
};
Имя службы servname
должно быть указано обязательно. Если задан и протокол (то есть если protoname
— непустой указатель), то в структуре должен быть указан совпадающий протокол. Некоторые службы Интернета позволяют использовать и TCP, и UDP (например, DNS и все службы, представленные в табл. 2.1), в то время как другие поддерживают только один протокол (протоколу FTP требуется TCP). Если аргумент protoname
не задан и служба поддерживает несколько протоколов, то возвращаемый номер порта зависит от реализации. Обычно это не имеет значения, поскольку службы, поддерживающие множество протоколов, как правило, используют один и тот же номер порта для протоколов TCP и UDP, но вообще говоря это не гарантируется.
Более всего в структуре servent
нас интересует поле номера порта. Поскольку номер порта возвращается в сетевом порядке байтов, мы не должны вызывать функцию htons
при записи его в структуру адреса сокета.
Типичные вызовы этой функции могут быть такими:
struct servent *sptr;
sptr = getservbyname("domain", "udp"); /* DNS с использованием UDP */
sptr = getservbyname("ftp", "tcp"); /* FTP с использованием TCP */
sptr = getservbyname("ftp", NULL); /* FTP с использованием TCP */
sptr = getservbyname("ftp", "udp"); /* этот вызов приведет к ошибке */
Поскольку протоколом FTP поддерживается только TCP, второй и третий вызовы эквивалентны, а четвертый вызов приводит к ошибке. Вот соответствующие строки из файла /etc/services
:
Читать дальше
Конец ознакомительного отрывка
Купить книгу