UNIX: разработка сетевых приложений
Самые современные распознаватели предоставляют функцию
, которая в качестве единственного аргумента получает значениеhstrerrorи возвращает указатель типаh_errnoна описание ошибки. Некоторые примеры строк, возвращаемых этой функцией, мы увидим в следующем примере.const char*Пример
В листинге 11.1 [1] показана простая программа, вызывающая функцию
для любого числа аргументов командной строки и выводящая всю возвращаемую информацию.gethostbynameЛистинг 11.1. Вызов функции и вывод возвращаемой информации
//names/hostent.c1 #include "unp.h"2 int3 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Сначала мы выполняем программу с именем нашего узла
, у которого имеется только один адрес IPv4:aixfreebsd % <b>hostent aix</b>official hostname: aix.unpbook.comaddress: 192.168 42.2Обратите внимание, что официальное имя узла — это FQDN. Кроме того, хотя у узла имеется адрес IPv6, возвращается только адрес IPv4. Следующим будет веб-сервер с несколькими адресами IPv4:
solaris % <b>hostent cnn.com</b>official hostname: cnn.comaddress: 64.236.16.20address: 64.236.16.52address: 64.236 16.84address: 64.236.16.116address: 64.236.24.4address: 64.236.24.12address: 64.236.24.20address: 64.236.24.28Далее идет имя, представленное в разделе 11.2 как имя с записью типа CNAME:
solaris % <b>hostent www</b>official hostname: linux.unpbook.comalias: www.unpbook.comaddress: 206.168.112.219Как мы и предполагали, официальное имя узла отличается от нашего аргумента командной строки.
Чтобы увидеть строки ошибок, возвращаемые функцией
, мы сначала задаем несуществующее имя узла, а затем имя, имеющее только запись типа MX:hstrerrorsolaris % <b>hostent nosuchname.invalid</b>gethostbyname error for host: nosuchname.invalid: Unknown hostsolaris % <b>hostent uunet.uu.net</b>gethostbyname error for host: uunet.uu.net: No address associated with name11.4 Функция gethostbyaddr
Функция
получает в качестве аргумента двоичный IP-адрес и пытается найти имя узла, соответствующее этому адресу. Ее действие обратно действию функцииgethostbyaddr.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*, содержащую адрес IPv4. Полеin_addr— это длина структуры: 4 для адресов IPv4. Аргументlenбудет иметь значениеfamily.AF_INET