UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
Мы только что показали, что сервер IPv6, работающий на узле с двойным стеком, может обрабатывать как клиенты IPv4, так и клиенты IPv6. Адреса IPv4-клиента передаются серверу IPv6 как адреса IPv4, преобразованные к виду IPv6, что мы рассматривали в разделе 12.2.
11.14. Функция udp_client
Наши функции, предоставляющие более простой интерфейс для функции
getaddrinfo#include "unp.h"int udp_client(const char *<i>hostname</i>, const char *<i>service</i>, void **<i>saptr</i>, socklen_t *<i>lenp</i>);<i>Возвращает: дескриптор неприсоединенного сокета в случае успешного выполнения, в случае ошибки не возвращает ничего</i>Эта функция создает неприсоединенный сокет UDP, возвращая три элемента. Во-первых, возвращаемое значение функции — это дескриптор сокета. Во-вторых,
saptrudp_clientsendtolenptcp_listensendtorecvfromВ листинге 11.9 показан исходный код для этой функции.
Листинг 11.9. Функция udp_client: создание неприсоединенного сокета UDP
//lib/udp_client.c 1 #include "unp.h" 2 int 3 udp_client(const char *host, const char *serv, void **saptr, socklen_t *lenp) 4 { 5 int sockfd, n; 6 struct addrinfo hints, *res, *ressave; 7 bzero(&hints, sizeof(struct addrinfo)); 8 hints.ai_family = AF_UNSPEC; 9 hints.ai_socktype = SOCK_DGRAM;10 if ((n = getaddrinfo(host, serv, &hints, &res)) != 0)11 err_quit("udp_client error for %s, %s: %s",12 host, serv, gai_strerror(n));13 ressave = res;14 do {15 sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);16 if (sockfd >= 0)17 break; /* успех */18 } while ((res = res->ai_next) != NULL);19 if (res == NULL) /* значение errno устанавливается при последнем вызове функции socket() */20 err_sys("udp_client error for %s, %s", host, serv);21 *saptr = Malloc(res->ai_addrlen);22 memcpy(*saptr, res->ai_addr, res->ai_addrlen);23 *lenp = res->ai_addrlen;24 freeaddrinfo(ressave);25 return (sockfd);26 }Функция
getaddrinfohostnameserviceПример: не зависящий от протокола UDP-клиент времени и даты
Теперь мы перепишем наш клиент времени и даты, показанный в листинге 11.3, так, чтобы в нем использовалась наша функция
udp_clientЛистинг 11.10. UDP-клиент времени и даты, использующий нашу функцию udp_client
//names/daytimeudpcli1.c 1 #include "unp.h" 2 int 3 main(int argc, char **argv) 4 { 5 int sockfd, n; 6 char recvline[MAXLINE + 1]; 7 socklen_t salen; 8 struct sockaddr *sa; 9 if (argc != 3)10 err_quit11 ("usage; daytimeudpcli1 <hostname/IPaddress> <service/port#>");12 sockfd = Udp_client(argv[1], argv[2], (void**)&sa, &salen);13 printf("sending to %sn", Sock_ntop_host(sa, salen));14 Sendto(sockfd, "", 1, 0, sa, salen); /* посылается 1-байтовая дейтаграмма */15 n = Recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL);16 recvline[n] = 0; /* завершающий пустой байт */17 Fputs(recvline, stdout);18 exit(0);19 }12-17udp_client
