UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
14 ressave = res;
15 do {
16 sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
17 if (sockfd < 0)
18 continue; /* ошибка, пробуем следующий адрес */
19 if (bind(sockfd, res->ai_addr, res->ai_addrlen) == 0)
20 break; /* успех */
21 Close(sockfd); /* ошибка при вызове функции bind, закрываем
сокет и пробуем следующий адрес */
22 } while ((res = res->ai_next) != NULL);
23 if (res == NULL) /* значение errno устанавливается при
последнем вызове функции socket() or bind() */
24 err_sys("udp_server error for %s, %s", host, serv);
25 if (addrlenp)
26 *addrlenp = res->ai_addrlen; /* возвращается размер адреса
протокола */
27 freeaddrinfo(ressave);
28 return (sockfd);
29 }
Эта функция практически идентична функции
tcp_listen
listen
AF_UNSPEC
Мы не устанавливаем параметр сокета
SO_REUSEADDR
Пример: не зависящий от протокола UDP-сервер времени и даты
В листинге 11.13 представлен наш сервер времени и даты, полученный путем модификации листинга 11.8 и предназначенный для использования UDP.
Листинг 11.13. Не зависящий от протокола UDP-сервер времени и даты
//names/daytimeudpsrv2.c
1 #include "unp.h"
2 #include <time.h>
3 int
4 main(int argc, char **argv)
5 {
6 int sockfd;
7 ssize_t n;
8 char buff[MAXLINE];
9 time_t ticks;
10 socklen_t addrlen, len;
11 struct sockaddr_storage cliaddr;
12 if (argc == 2)
13 sockfd = Udp_server(NULL, argv[1], &addrlen);
14 else if (argc == 3)
15 sockfd = Udp_server(argv[1], argv[2], &addrlen);
16 else
17 err_quit("usage: daytimeudpsrv [ <host> ] <service or port>");
18 for (;;) {
19 len = sizeof(cliaddr);
20 n = Recvfrom(sockfd, buff, MAXLINE, 0, (SA*)&cliaddr, &len);
21 printf("datagram from %sn", Sock_ntop((SA*)&cliaddr, len));
22 ticks = time(NULL);
23 snprintf(buff, sizeof(buff), "% 24srn", ctime(&ticks));
24 Sendto(sockfd, buff, strlen(buff), 0, (SA*)&cliaddr, len);
25 }
26 }
11.17. Функция getnameinfo
Эта функция дополняет функцию
getaddrinfo
#include <netdb.h>
int getnameinfo(const struct sockaddr *<i>sockaddr</i>, socklen_t <i>addrlen</i>, char *<i>host</i>,
size_t <i>hostlen</i>, char *<i>serv</i>, size_t <i>servlen</i>, int <i>flags</i>);
<i>Возвращает 0 в случае успешного выполнения, -1 в случае ошибки</i>
Аргумент
sockaddr
addrlen
accept
recvfrom
getsockname
getpeername
Вызывающий процесс выделяет в памяти пространство для двух строк, удобных для человеческого восприятия: аргументы
host
hostlen
serv
servlen
hostlen
servlen