Самые современные распознаватели предоставляют функцию
hstrerror
, которая в качестве единственного аргумента получает значение
h_errno
и возвращает указатель типа
const char*
на описание ошибки. Некоторые примеры строк, возвращаемых этой функцией, мы увидим в следующем примере.
Пример
В листинге 11.1[1] показана простая программа, вызывающая функцию
gethostbyname
для любого числа аргументов командной строки и выводящая всю возвращаемую информацию.
Листинг 11.1. Вызов функции и вывод возвращаемой информации
//names/hostent.c
1 #include "unp.h"
2 int
3 main(int argc, char **argv)
4 {
5 char *ptr, **pptr;
6 char str[INET_ADDRSTRLEN];
7 struct hostent *hptr;
8 while (--argc > 0) {
9 ptr = *++argv;
10 if ((hptr = gethostbyname(ptr)) == NULL) {
11 err_msg("gethostbyname error for host, %s: %s",
12 ptr, hstrerror(h_errno));
13 continue;
14 }
15 printf("official hostname: %s\n", hptr->h_name);
16 for (pptr = hptr->h_aliases; *pptr != NULL; pptr++)
17 printf("\talias: %s\n", *pptr);
18 switch (hptr->h_addrtype) {
19 case AF_INET:
20 pptr = hptr->h_addr_list;
21 for (; *pptr != NULL; pptr++)
22 printf("\taddress: %s\n",
23 Inet_ntop(hptr->h_addrtype, *pptr, str, sizeof(str)));
24 break;
25 default:
26 err_ret("unknown address type");
27 break;
28 }
29 }
30 exit(0);
31 }
8-14
Функция
gethostbyname
вызывается для каждого аргумента командной строки.
15-17
Выводится каноническое имя узла, за которым идет список альтернативных имен.
18-24
Переменная
pptr
указывает на массив указателей на индивидуальные адреса. Для каждого адреса мы вызываем функцию
inet_ntop
и выводим возвращаемую строку.
Сначала мы выполняем программу с именем нашего узла
aix
, у которого имеется только один адрес IPv4:
freebsd % <b>hostent aix</b>
official hostname: aix.unpbook.com
address: 192.168 42.2
Обратите внимание, что официальное имя узла — это FQDN. Кроме того, хотя у узла имеется адрес IPv6, возвращается только адрес IPv4. Следующим будет веб-сервер с несколькими адресами IPv4:
solaris % <b>hostent cnn.com</b>
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 % <b>hostent www</b>
official hostname: linux.unpbook.com
alias: www.unpbook.com
address: 206.168.112.219
Как мы и предполагали, официальное имя узла отличается от нашего аргумента командной строки.
Чтобы увидеть строки ошибок, возвращаемые функцией
hstrerror
, мы сначала задаем несуществующее имя узла, а затем имя, имеющее только запись типа MX:
solaris % <b>hostent nosuchname.invalid</b>
gethostbyname error for host: nosuchname.invalid: Unknown host
solaris % <b>hostent uunet.uu.net</b>
gethostbyname error for host: uunet.uu.net: No address associated with name
11.4 Функция gethostbyaddr
Функция
gethostbyaddr
получает в качестве аргумента двоичный IP-адрес и пытается найти имя узла, соответствующее этому адресу. Ее действие обратно действию функции
gethostbyname
.
#include <netdb.h>
struct hostent *gethostbyaddr(const char *<i>addr</i>, size_t <i>len</i>, int <i>family</i>);
<i>Возвращает: непустой указатель в случае успешного выполнения, -1 в случае ошибки</i>
Эта функция возвращает указатель на ту же структуру
hostent
, которую мы описывали при рассмотрении функции
gethostbyname
. Обычно в этой структуре нас интересует поле
h_name
, каноническое имя узла.
Аргумент
addr
не относится к типу
char*
, но в действительности это указатель на структуру
in_addr
, содержащую адрес IPv4. Поле
len
— это длина структуры: 4 для адресов IPv4. Аргумент
family
будет иметь значение
AF_INET
.