11.14. Функция udp_client

We use cookies. Read the Privacy and Cookie Policy

11.14. Функция udp_client

Наши функции, предоставляющие более простой интерфейс для функции getaddrinfo, в случае UDP изменяются: в этом разделе мы представляем клиентскую функцию, создающую неприсоединенный сокет UDP, а в следующем — другую функцию, создающую присоединенный сокет UDP.

#include "unp.h"

int udp_client(const char *hostname, const char *service,

 void **saptr, socklen_t *lenp);

Возвращает: дескриптор неприсоединенного сокета в случае успешного выполнения, в случае ошибки не возвращает ничего

Эта функция создает неприсоединенный сокет UDP, возвращая три элемента. Во-первых, возвращаемое значение функции — это дескриптор сокета. Во-вторых, saptr — это адрес указателя (объявляемого вызывающим процессом) на структуру адреса сокета (которая динамически размещается в памяти функцией udp_client), и в этой структуре функция хранит IP-адрес получателя и номер порта для будущих вызовов функции sendto. Размер этой структуры адреса сокета возвращается как значение переменной, на которую указывает lenp. Последний аргумент не может быть пустым указателем (как это допустимо для последнего аргумента функции tcp_listen), поскольку длина структуры адреса сокета требуется в любых вызовах функций sendto и recvfrom.

В листинге 11.9 показан исходный код для этой функции.

Листинг 11.9. Функция udp_client: создание неприсоединенного сокета UDP

//lib/udp_client.c

 1 #include "unp.h"

 2 int

 3 udp_client(const char *host, const char *serv, void **saptr, socklen_t *lenp)

 4 {

 5  int sockfd, n;

 6  struct addrinfo hints, *res, *ressave;

 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. Создается дейтаграммный сокет. Выделяется память для одной структуры адреса сокета, и структура адреса сокета, соответствующая созданному сокету, копируется в память.

Данный текст является ознакомительным фрагментом.