UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
Листинг 11.2. Наш клиент времени и даты, использующий функции gethostbyname и getservbyname
//names/daytimetcpcli1.c
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_in servaddr;
8 struct in_addr **pptr;
9 struct in_addr *inetaddrp[2];
10 struct in_addr inetaddr;
11 struct hostent *hp;
12 struct servent *sp;
13 if (argc != 3)
14 err_quit("usage: daytimetcpcli1 <hostname> <service>");
15 if ((hp = gethostbyname(argv[1])) == NULL) {
16 if (inet_aton(argv[1], &inetaddr) == 0) {
17 err_quit("hostname error for %s: %s", argv[1],
18 hstrerror(h_errno));
19 } else {
20 inetaddrp[0] = &inetaddr;
21 inetaddrp[1] = NULL;
22 pptr = inetaddrp;
23 }
24 } else {
25 pptr = (struct in_addr**)hp->h_addr_list;
26 }
27 if ((sp = getservbyname(argv[2], "tcp")) == NULL)
28 err_quit("getservbyname error for %s", argv[2]);
29 for (; *pptr != NULL; pptr++) {
30 sockfd = Socket(AF_INET, SOCK_STREAM, 0);
31 bzero(&servaddr, sizeof(servaddr));
32 servaddr.sin_family = AF_INET;
33 servaddr.sin_port = sp->s_port;
34 memcpy(&servaddr.sin_addr, *pptr, sizeof(struct in_addr));
35 printf("trying %sn", Sock_ntop((SA*)&servaddr, sizeof(servaddr)));
36 if (connect(sockfd, (SA*)&servaddr, sizeof(servaddr)) == 0)
37 break; /* успешное завершение */
38 err_ret("connect error");
39 close(sockfd);
40 }
41 if (*pptr == NULL)
42 err_quit("unable to connect");
43 while ((n = Read(sockfd, recvline, MAXLINE)) > 0) {
44 recvline[n] = 0; /* null terminate */
45 Fputs(recvline, stdout);
46 }
47 exit(0);
48 }
13-28
gethostbyname
getservbyname
getservbyname
gethostbyname
inet_aton
29-35
socket
connect
connect
socket
bzero
36-39
connect
break
connect
41-42
connect
43-47
Если мы запустим эту программу, указав один из наших узлов, на котором работает сервер времени и даты, мы получим ожидаемый результат:
freebsd % <b>daytimetcpcli1 aix daytime</b>
trying 192.168.42.2:13
Sun Jul 27 22:44:19 2003
Но еще интереснее запустить программу, обратившись к маршрутизатору с несколькими сетевыми интерфейсами, на котором не работает сервер времени и даты:
solaris % <b>daytimetcpcli1 gateway.tuc.noao.edu daytime</b>
trying 140.252.108.1:13