Вход/Регистрация
UNIX: разработка сетевых приложений
вернуться

Стивенс Уильям Ричард

Шрифт:

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 }

Функция

getaddrinfo
преобразует аргументы
hostname
и
service
. Создается дейтаграммный сокет. Выделяется память для одной структуры адреса сокета, и структура адреса сокета, соответствующая созданному сокету, копируется в память.

Пример: не зависящий от протокола UDP-клиент времени и даты

Теперь мы перепишем наш клиент времени и даты, показанный в листинге 11.3, так, чтобы в нем использовалась наша функция

udp_client
. В листинге 11.10 представлен не зависящий от протокола исходный код.

Листинг 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_quit

11 ("usage; daytimeudpcli1 <hostname/IPaddress> <service/port#>");

12 sockfd = Udp_client(argv[1], argv[2], (void**)&sa, &salen);

13 printf("sending to %s\n", 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-17
Мы вызываем нашу функцию
udp_client
и затем выводим IP-адрес и порт сервера, которому мы отправим нашу дейтаграмму UDP. Мы посылаем однобайтовую дейтаграмму и затем читаем и выводим ответ сервера.

ПРИМЕЧАНИЕ

Нам достаточно отправить дейтаграмму, содержащую 0 байт, поскольку ответ сервера времени и даты инициируется самим получением дейтаграммы от клиента, независимо от ее длины и содержания. Но многие реализации SVR4 не допускают нулевой длины дейтаграмм UDP.

Мы запускаем наш клиент, задавая имя узла с записью типа AAAA и типа А. Поскольку функция

getaddrinfo
в первую очередь возвращает структуру с записью типа AAAA, создается сокет IPv6:

  • Читать дальше
  • 1
  • ...
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: