Уильям Стивенс - UNIX: разработка сетевых приложений
- Название:UNIX: разработка сетевых приложений
- Автор:
- Жанр:
- Издательство:Питер
- Год:2007
- Город:Санкт-Петербург
- ISBN:5-94723-991-4
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Уильям Стивенс - UNIX: разработка сетевых приложений краткое содержание
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
UNIX: разработка сетевых приложений - читать онлайн бесплатно ознакомительный отрывок
Интервал:
Закладка:
Самая основная функция, выполняющая поиск имени узла, — это функция gethostbyname
. При успешном выполнении она возвращает указатель на структуру hostent
, содержащую все адреса IPv4 для узла. Однако она может возвращать только адреса IPv4. В разделе 11.6 рассматривается функция, возвращающая адреса IPv4 и IPv6. Стандарт POSIX предупреждает, что функция gethostbyname
может быть исключена из будущей его версии.
Маловероятно, что реализации gethostbyname исчезнут раньше, чем весь Интернет перейдет на протокол IPv6, а произойдет это еще очень не скоро. Однако удаление функции из стандарта POSIX гарантирует, что она не будет использоваться в новых программах. Вместо нее мы рекомендуем использовать getaddrinfo (раздел 11.6).
#include
struct hostent *gethostbyname(const char * hostname );
Возвращает: непустой указатель в случае успешного выполнения, -1 в случае ошибки
Непустой указатель, возвращаемый этой функцией, указывает на следующую структуру hostent
:
struct hostent {
char *h_name; /* официальное (каноническое) имя узла */
char **h_alihases; /* указатель на массив указателей на псевдонимы */
int h_addrtype; /* тип адреса узла: AF_INET */
int h_length; /* длина адреса: 4 */
char **h_addr_list; /* указатель на массив указателей с адресами IPv4 или IPv6 */
};
В терминах DNS функция gethostbyname
выполняет запрос на запись типа А. Функция возвращает только адреса IPv4.
На рис. 11.2 представлено устройство структуры hostent
и содержащаяся в ней информация, в предположении, что искомое имя узла имеет два альтернативных имени и три адреса IPv4. Все имена узла представляют собой строки языка С.

Рис. 11.2. Структура hostent и ее одержимое
Возвращаемое имя h_name
называется каноническим именем узла. Например, с показанными в предыдущем разделе записями CNAME каноническое имя узла ftp://ftp.unpbook.com
будет иметь вид linux.unpbook.com
. Также если мы вызываем функцию gethostbyname
с узла aix
с неполным именем, например solaris
, то в качестве канонического имени возвращается полное доменное имя (FQDN) solaris.unpbook.com.
.
Некоторые версии функции gethostbyname допускают, что аргумент hostname может быть записан в виде строки десятичных чисел, разделенных точками. То есть вызов в форме hptr = gethostbyname("206.62.226.33"); будет работать. Этот код был добавлен, поскольку клиент Rlogin принимает только имя узла, вызывая функцию gethostbyname, и не принимает точечно-десятичную запись [127]. Стандарт POSIX допускает это, но не устанавливает такое поведение в качестве обязательного, поэтому переносимое приложение не может использовать указанную особенность.
Функция gethostbyname
отличается от других функций сокетов, описанных нами, тем, что она не задает значение переменной errno
, когда происходит ошибка. Вместо этого она присваивает глобальной целочисленной переменной h_errno
одну из следующих констант, определяемых в заголовке :
■ HOST_NOT_FOUND
;
■ TRY_AGAIN
;
■ NO_RECOVERY
;
■ NO_DATA
(идентично NO_ADDRESS
).
Ошибка NO_DATA
означает, что заданное имя действительно, но у него нет записи типа А. Примером может служить имя узла, имеющего только запись типа MX.
Самые современные распознаватели предоставляют функцию hstrerror
, которая в качестве единственного аргумента получает значение h_errno
и возвращает указатель типа const char*
на описание ошибки. Некоторые примеры строк, возвращаемых этой функцией, мы увидим в следующем примере.
Пример
В листинге 11.1 [1] Все исходные коды программ, опубликованные в этой книге, вы можете найти по адресу http://www.piter.com.
показана простая программа, вызывающая функцию 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 % hostent aix
official hostname: aix.unpbook.com
address: 192.168 42.2
Обратите внимание, что официальное имя узла — это FQDN. Кроме того, хотя у узла имеется адрес IPv6, возвращается только адрес IPv4. Следующим будет веб-сервер с несколькими адресами IPv4:
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 );
Интервал:
Закладка: