11.16. Функция udp_server
11.16. Функция udp_server
Наша последняя функция, предоставляющая более простой интерфейс для функции getaddrinfo, — это функция udp_server.
#include "unp.h"
int udp_server(const char *hostname, const char *service, socklen_t *lenptr);
Возвращает; дескриптор неприсоединенного сокета в случае успешного выполнения, в случае ошибки не возвращает ничего
Аргументы функции те же, что и для функции tcp_listen: необязательный hostname, обязательный service (для связывания номер порта) и необязательный указатель на переменную, в которой возвращается размер структуры адреса сокета. В листинге 11.12 представлен исходный код.
Листинг 11.12. Функция udp_server: создание неприсоединенного сокета для сервера UDP
//lib/udp_server.c
1 #include "unp.h"
2 int
3 udp_server(const char *host, const char *serv, socklen_t *addrlenp)
4 {
5 int sockfd, n;
6 struct addrinfo hints, *res, *ressave;
7 bzero(&hints, sizeof(struct addrinfo));
8 hints.ai_flags = AI_PASSIVE;
9 hints.ai_family = AF_UNSPEC;
10 hints.ai_socktype = SOCK_DGRAM;
11 if ((n = getaddrinfo(host, serv, &hints, &res)) != 0)
12 err_quit("udp_server error for %s, %s: %s",
13 host, serv, gai_strerror(n));
14 ressave = res;
15 do {
16 sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
17 if (sockfd < 0)
18 continue; /* ошибка, пробуем следующий адрес */
19 if (bind(sockfd, res->ai_addr, res->ai_addrlen) == 0)
20 break; /* успех */
21 Close(sockfd); /* ошибка при вызове функции bind, закрываем
сокет и пробуем следующий адрес */
22 } while ((res = res->ai_next) != NULL);
23 if (res == NULL) /* значение errno устанавливается при
последнем вызове функции socket() or bind() */
24 err_sys("udp_server error for %s, %s", host, serv);
25 if (addrlenp)
26 *addrlenp = res->ai_addrlen; /* возвращается размер адреса
протокола */
27 freeaddrinfo(ressave);
28 return (sockfd);
29 }
Эта функция практически идентична функции tcp_listen, в ней нет только вызова функции listen. Мы устанавливаем семейство адресов AF_UNSPEC, но вызывающий процесс может использовать ту же технологию, которую мы описали при рассмотрении листинга 11.6, чтобы потребовать использование определенного протокола (IPv4 или IPv6).
Мы не устанавливаем параметр сокета SO_REUSEADDR для сокета UDP, поскольку этот параметр сокета может допустить связывание множества сокетов с одним и тем же портом UDP на узлах, поддерживающих многоадресную передачу, как мы говорили в разделе 7.5. Поскольку у сокета UDP нет аналога состояния TIME_WAIT, свойственного сокетам TCP, нет необходимости устанавливать этот параметр при запуске сервера.
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКДанный текст является ознакомительным фрагментом.
Читайте также
Функция pthread_rwlock_rdlock
Функция pthread_rwlock_rdlock Текст функции pthread_rwlock_rdlock приведен в листинге 8.4.Листинг 8.4. Функция pthread_rwlock_rdlock: получение блокировки на чтение//my_rwlock/pthread_rwlock_rdlock.с1 #include "unpipc.h"2 #include "pthread_rwlock.h"3 int4 pthread_rwlock_rdlock(pthread_rwlock_t *rw)5 {6 int result;7 if (rw->rw_magic != RW_MAGIC)8 return(EINVAL);9 if ((result =
Функция pthread_rwlock_tryrdlock
Функция pthread_rwlock_tryrdlock В листинге 8.5 показана наша реализация функции pthread_rwlock_tryrdlock, которая не вызывает приостановления вызвавшего ее потока.Листинг 8.5. Функция pthread_rwlock_tryrdlock: попытка заблокировать ресурс для чтения//my_rwlock/pthread_rwlock_tryrdlock.с1 #include "unpipc.h"2 #include
Функция pthread_rwlock_wrlock
Функция pthread_rwlock_wrlock Текст функции pthread_rwlock_wrlock приведен в листинге 8.6.11-17 Если ресурс заблокирован на считывание или запись (значение rw_refcount отлично от 0), мы приостанавливаем выполнение потока. Для этого мы увеличиваем rw_nwaitwriters и вызываем pthread_cond_wait с условной переменной
Функция pthread_rwlock_trywrlock
Функция pthread_rwlock_trywrlock Неблокируемая функция pthread_rwlock_trywrlock показана в листинге 8.7.11-14 Если значение счетчика rw_refcount отлично от нуля, блокировка в данный момент уже установлена считывающим или записывающим процессом (это безразлично) и мы возвращаем ошибку с кодом EBUSY. В
Функция sem_open
Функция sem_open В листинге 10.22 приведен текст функции sem_open, которая создает новый семафор или открывает существующий.Листинг 10.22. Функция sem_open//my_pxsem_fifo/sem_open.с1 #include "unpipc.h"2 #include "semaphore.h"3 #include <stdarg.h> /* для произвольного списка аргументов */4 mysem_t *5 mysem_open(const char *pathname, int
Функция SUM
Функция SUM Ваши возможности в подведении итогов не ограничены простым подсчетом записей. Используя функцию SUM, можно генерировать итоговые результаты для всех возвращаемых записей по любым числовым полям. Например, для создания запроса, который генерирует итоги по
Функция uni()
Функция uni() Поиск/замена символа по его юникодному номеру также может быть сделана при помощи функции uni().Пример функции uni(): Boouni(107,32)Designer найдет слово Book
Функция uni()
Функция uni() Поиск/замена символа по его юникодному номеру также может быть сделана при помощи функции uni().Пример функции uni(): Boouni(107,32)Designer найдет слово Book
Хэш-функция.
Хэш-функция. Еще одно важное преимущество использования PGP состоит в том, что PGP применяет так называемую «хэш-функцию», которая действует таким образом, что в том случае какого-либо изменения информации, пусть даже на один бит, результат «хэш-функции» будет совершенно
Функция uni()
Функция uni() Поиск/замена символа по его юникодному номеру также может быть сделана при помощи функции uni().Пример функции uni(): Boouni(107,32)Designer найдет слово Book
Хэш-функция
Хэш-функция Однако описанная выше схема имеет ряд существенных недостатков. Она крайне медлительна и производит слишком большой объём данных — по меньшей мере вдвое больше объёма исходной информации. Улучшением такой схемы становится введение в процесс преобразования