Пример: сервер времени и даты
Пример: сервер времени и даты
В листинге 11.7 показан наш сервер времени и даты из листинга 4.2, переписанный с использованием функции tcp_listen.
Листинг 11.7. Сервер времени и даты, переписанный с использованием функции tcp_listen
//names/daytimetcpsrv1.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 char = buff[MAXLINE];
9 time_t ticks;
10 struct sockaddr_storage cliaddr;
11 if (argc != 2)
12 err_quit("usage: daytimetcpsrv1 <service or port#>");
13 listenfd = Tcp_listen(NULL, argv[1], &addrlen);
14 for (;;) {
15 len = sizeof(cliaddr);
16 connfd = Accept(listenfd, (SA*)&cliaddr, &len);
17 printf("connection from %s ", Sock_ntop((SA*)&cliaddr, len));
18 ticks = time(NULL);
19 snprintf(buff, sizeof(buff), "%.24s ", ctime(&ticks));
20 Write(connfd, buff, strlen(buff));
21 Close(connfd);
22 }
23 }
Ввод имени службы или номера порта в качестве аргумента командной строки
11-12 Нам нужно использовать аргумент командной строки, чтобы задать либо имя службы, либо номер порта. Это упрощает проверку нашего сервера, поскольку связывание с портом 13 для сервера времени и даты требует прав привилегированного пользователя.
Создание прослушиваемого сокета
13 Функция tcp_listen создает прослушиваемый сокет. В качестве третьего аргумента мы передаем нулевой указатель, потому что нам безразличен размер структуры адреса, используемого данным семейством: мы будем работать со структурой sockaddr_storage.
Цикл сервера
14-22 Функция accept ждет соединения с клиентом. Мы выводим адрес клиента, вызывая функцию sock_ntop. В случае IPv4 или IPv6 эта функция выводит IP-адрес и номер порта. Мы могли бы использовать функцию getnameinfo (описанную в разделе 11.17), чтобы попытаться получить имя узла клиента, но это подразумевает запрос PTR в DNS, что может занять некоторое время, особенно если запрос PTR окажется неудачным. В разделе 14.8 [112] упоминается, что на занятом веб-сервере почти у 25% всех клиентов, соединяющихся с этим сервером, в DNS нет записей типа PTR. Поскольку мы не хотим, чтобы наш сервер (особенно последовательный сервер) в течение нескольких секунд ждал запрос PTR, мы просто выводим IP-адрес и порт.
Данный текст является ознакомительным фрагментом.