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

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

Шрифт:

16 addrcnt++;

17 p += addr->ai_addrlen;

18 }

19 Sctp_bindx(sock_fd, (SA*)bindbuf, addrent, SCTP_BINDX_ADD_ADDR);

20 free(bindbuf);

21 return(0);

22 }

Выделение памяти под аргументы bind

9-10
Наша новая функция начинает работу с выделения памяти под аргументы функции
sctp_bindx
. Обратите внимание, что функция
sctp_bindx
может принимать в качестве аргументов адреса IPv4 и IPv6 в произвольных комбинациях. Для каждого адреса мы выделяем место под структуру
sockaddr_storage
несмотря на то, что соответствующий аргумент
sctp_bindx
представляет собой упакованный список адресов (см. рис. 9.3). В результате мы расходуем зря некоторый объем памяти, но зато функция работает быстрее, потому что ей не приходится вычислять точный объем памяти и лишний раз обрабатывать список аргументов.

Обработка аргументов

11-18
Мы подготавливаем
portbuf
к хранению номера порта в ASCII-представлении, имея в виду вызов нашей обертки для
getaddrinfo
, которая называется
host_serv
. Каждый адрес с номером порта мы передаем
host_serv
, указывая константы
AF_UNSPEC
(протоколы IPv4 и IPv6) и
SOCK_SEQPACKET
(протокол SCTP). Мы копируем первую возвращаемую структуру
sockaddr
, игнорируя все остальные. Поскольку аргументами этой функции должны быть адреса в строковом представлении, а не имена, с каждым из которых может быть связано несколько адресов, это не вызывает проблем. Мы освобождаем буфер, увеличиваем количество адресов на единицу и перемещаем указатель на следующий элемент в упакованном массиве структур
sockaddr
.

Вызов связывающей функции

19
Указатель устанавливается на начало буфера адресов, после чего вызывается функция
sctp_bindx
, в качестве аргументов которой используется раскодированный ранее набор адресов.

Успешное завершение

20-21
Если мы добрались до этого места, можно считать, что выполнение прошло успешно, поэтому мы освобождаем память и возвращаем управление вызвавшему процессу.

В листинге 23.8 представлен модифицированный эхо-сервер, связывающий сокет с набором адресов, передаваемых в командной строке. Мы слегка изменили код сервера, чтобы он отправлял эхо-сообщения по тем потокам, по которым были приняты исходные сообщения.

Листинг 23.8. Сервер, работающий с произвольным набором адресов

if (argc < 2)

err_quit("Error, use %s [list of addresses to bind]\n", argv[0]);

sock_fd = Socket(AF_INET6, SOCK_SEQPACKET, IPPROTO_SCTP);

if (sctp_bind_arg_list(sock_fd, argv + 1, argc — 1))

err_sys("Can't bind the address set");

bzero(&evnts, sizeof(evnts));

evnts sctp_data_io_event = 1;

Работа с IPv6

14
Это тот же сервер, с которым мы работали во всех предыдущих разделах этой главы, но с незначительным изменением. Сервер создает сокет
AF_INET6
, что позволяет ему работать с протоколом IP обеих версий.

Вызов sctp_bind_arg_list

15-16
Сервер вызывает новую функцию
sctp_bind_arg_list
и передает ей список аргументов для обработки.

23.7. Получение адресов

Поскольку протокол SCTP ориентирован на многоинтерфейсные узлы, для определения адресов локального и удаленного узла не могут использоваться те же механизмы, что и в TCP. В этом разделе мы изменим код клиента, добавив в него подписку на уведомление о событии COMMUNICATION UP. В этом уведомлении клиент будет получать сведения об адресах, между которыми установлена ассоциация. В листингах 23.9 и 23.10 представлены изменения в коде клиента. Листинги 23.11 и 23.12 содержат добавления к коду клиента.

Листинг 23.9. Клиент включает уведомления

16 bzero(&evnts, sizeof(evnts));

17 evnts.sctp_data_io_event = 1;

18 evnts.sctp_association_event = 1;

19 Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS, &evnts, sizeof(evnts));

20 sctpstr_cli(stdin, sock_fd, (SA*)&servaddr, sizeof(servaddr));

Включение событий и вызов функции отправки сообщения

16-20
Функция
main
клиента претерпевает не слишком значительные изменения. Клиент явным образом подписывается на уведомления об изменении состояния ассоциации.

Посмотрим, что нам придется изменить в функции

sctpstr_cli
, чтобы она смогла вызывать нашу новую функцию обработки уведомлений.

Листинг 23.10. Функция sctp_strcli, способная работать с уведомлениями

21 do {

22 len = sizeof(peeraddr);

  • Читать дальше
  • 1
  • ...
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • ...

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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