1.3. Независимость от протокола
1.3. Независимость от протокола
Наша программа, представленная в листинге 1.1, является зависимой от протокола (protocol dependent) IPv4. Мы выделяем и инициализируем структуру sockaddr_in, определяем адрес как относящийся к семейству AF_INET и устанавливаем первый аргумент функции socket равным AF_INET.
Если мы хотим изменить программу так, чтобы она работала по протоколу IPv6, мы должны изменить код. В листинге 1.2 показана новая версия программы с соответствующими изменениями, отмеченными полужирным шрифтом.
Листинг 1.2. Версия листинга 1.1 для IPv6
//intro/daytimetcpcliv6.с
1 #include "unp.h"
2 int
3 main(int argc, char **argv)
4 {
5 int sockfd, n;
6 char recvline[MAXLINE + 1];
7 struct sockaddr_in6 servaddr;
8 if (argc != 2)
9 err_quit("usage: a.out <Ipaddress>");
10 if ((sockfd = socket(AF_INET6, SOCK_STREAM, 0)) < 0)
11 err_sys("socket error");
12 bzero(&servaddr, sizeof(servaddr));
13 servaddr.sin6_family = AF_INET6;
14 servaddr.sin6_port = htons(13); /* сервер времени и даты */
15 if (inet_pton(AF_INET6, argv[1], &servaddr.sin6_addr) <= 0)
16 err_quit("inet_pton error for %s", argv[1]);
17 if (connect(sockfd, (SA*)&servaddr, sizeof(servaddr)) < 0)
18 err_sys("connect error");
19 while ((n = read(sockfd, recvline, MAXLINE)) > 0) {
20 recvline[n] = 0; /* символ конца строки */
21 if (fputs(recvline, stdout) == EOF)
22 err_sys("fputs error");
23 }
24 if (n < 0)
25 err_sys("read error");
26 exit(0);
27 }
Изменились только пять строк, но в результате мы все равно получили программу, зависимую от протокола, в данном случае — от протокола IPv6. Лучше сделать программу независимой от протокола (protocol independent). В листинге 11.3 представлена независимая от протокола версия этого клиента, основанная на вызове getaddrinfo из tcp_connect.
Другим недостатком наших программ является то, что пользователь должен вводить IP-адрес сервера в точечно-десятичной записи (например, 206.168.112.219 для версии IPv4). Людям проще работать с именами, чем с числами (например, www.unpbook.com). В главе 11 мы обсудим функции, обеспечивающие преобразование имен узлов в IP-адреса и имен служб в порты. Мы специально откладываем описание этих функций, продолжая использовать IP-адреса и номера портов, чтобы иметь ясное представление о том, что именно входит в структуры адресов сокетов, которые мы должны заполнить и проверить. Это также упрощает наши объяснения сетевого программирования, снимая необходимость описывать в подробностях еще один набор функций.
Данный текст является ознакомительным фрагментом.