UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
14-22acceptsock_ntopgetnameinfoПример: сервер времени и даты с указанием протокола
В листинге 11.7 есть небольшая проблема: первый аргумент функции
tcp_listenAF_UNSPECtcp_listengetaddrinfoУ клиентов такой проблемы нет, поскольку клиент должен всегда задавать либо IP-адрес, либо имя узла. Клиентские приложения обычно позволяют пользователю вводить этот параметр как аргумент командной строки. Это дает нам возможность задавать имя узла, связанное с определенным типом IP-адреса (вспомните наши имена узлов -4 и -6 в разделе 11.2), или же задавать либо строку в точечно-десятичной записи (для IPv4), либо шестнадцатеричную строку (для IPv6).
И для серверов существует простая методика, позволяющая нам указать, какой именно протокол следует использовать — IPv4 или IPv6. Для этого нужно позволить пользователю ввести либо IP-адрес, либо имя узла в качестве аргумента командной строки и передать его функции
getaddrinfoinet_ptoninet_pton(AF_INET, "0.0.0.0", &foo); /* успешно */inet_pton(AF_INET, "0::0", &foo); /* неудачно*/inet_pton(AF_INET6, "0.0.0.0", &foo); /* неудачно */inet_pton(AF_INET6, "0::0", &foo); /* успешно */Следовательно, если мы изменим наши серверы таким образом, чтобы они получали дополнительный аргумент, то при вводе
% <b>server</b>по умолчанию мы получим IPv6 на узле с двойным стеком, но при вводе
% <b>server 0.0.0.0</b>явно задается IPv4, а при вводе
% <b>server 0::0</b>явно задается IPv6.
В листинге 11.8 показана окончательная версия нашего сервера времени и даты.
Листинг 11.8. Не зависящий от протокола сервер времени и даты, использующий функцию tcp_listen
names/daytimetcpsrv2.c 1 #include "unp.h" 2 #include <time.h> 3 int 4 main(int argc, char **argv) 5 { 6 int listenfd, connfd; 7 socklen_t addrlen, len; 8 struct sockaddr_storage cliaddr; 9 char buff[MAXLINE];10 time_t ticks;11 if (argc == 2)12 listenfd = Tcp_listen(NULL, argv[1], &addrlen);13 else if (argc == 3)14 listenfd = Tcp_listen(argv[1], argv[2], &addrlen);15 else16 err_quit("usage; daytimetcpsrv2 [ <host> ] <service or port>");17 for (;;) {18 len = sizeof(cliaddr);19 connfd = Accept(listenfd, (SA*)&cliaddr, &len);20 printf("connection from %sn", Sock_ntop((SA*)&cliaddr, len));21 ticks = time(NULL);21 snprintf(buff, sizeof(buff), "%.24srn", ctime(&ticks));23 Write(connfd, buff, strlen(buff));24 Close(connfd);25 }26 }11-16Сначала мы запускаем этот сервер с сокетом IPv4 и затем соединяемся с сервером от клиентов на двух различных узлах, расположенных в локальной подсети:
freebsd % <b>daytimetcpsrv2 0.0.0.0 9999</b>connection from 192.168.42.2:32961connection from 192.168.42.2:1389А теперь мы запустим сервер с сокетом IPv6:
solaris % <b>daytimetcpsrv2 0::0 9999</b>connection from [3ffe:b80:1f8d:2:204:acff:fe17:bf38]:32964connection from [3ffe:b80:1f8d:2:230:65ff:fe15:caa7]:49601connection from [::ffff:192:168:42:3]:32967connection from [::ffff:192:168:42:3]:49602Первое соединение — от узла
aixmacosxaixmacosxaccept
