UNIX: разработка сетевых приложений
Часть 264 из 399 Информация о книге
22 }23 }24 }Проверка типа уведомленияФункция преобразует буфер приема к типу универсального указателя на уведомления, чтобы определить тип полученного уведомления. Из всех уведомлений нас интересуют только уведомления об изменении ассоциации, а из них — уведомления о создании или перезапуске ассоциации (9-13иSCTP_COMM_UP). Все прочие уведомления нас не интересуют.SCTP_RESTARTПолучение и вывод адресов собеседникаФункция14-17возвращает нам список удаленных адресов, которые мы выводим при помощи функцииsctp_getpaddrs, представленной в листинге 23.12. После работы с ней мы освобождаем ресурсы, выделенныеsctp_print_addresses, вызывая функциюsctp_getpaddrs.sctp_freepaddrsПолучение и вывод локальных адресовФункция18-21возвращает нам список локальных адресов, которые мы выводим на экран вместе с их общим количеством. После завершения работы с адресами мы освобождаем память вызовомsctp_getladdrs.sctp_freeladdrsПоследняя из новых функций называется
. Она выводит на экран адреса из списка, возвращаемого функциямиsctp_print_addressesиsctp_getpaddrs. Текст функции представлен в листинге 23.12.sctp_getladdrsЛистинг 23.12. Вывод списка адресов
//sctp/sctp_print_addrs.c1 #include "unp.h"2 void3 sctp_print_addresses(struct sockaddr_storage *addrs, int num)4 {5 struct sockaddr_storage *ss;6 int i, salen;7 ss = addrs;8 for (i=0; i<num; i++){9 printf("%s\n", Sock_ntop((SA*)ss, salen));10 #ifdef HAVE_SOCKADDR_SA_LEN11 salen = ss->ss_len;12 #else13 swilch (ss->ss_family) {14 case AF_INET:15 salen = sizeof(struct sockaddr_in);16 break;17 #ifdef IPV618 case AF_INET6:19 salen = sizeof(struct sockaddr_in6);20 break;21 #endif22 default:23 err_auit("sctp_print_addresses: unknown AF");24 break;25 }26 #endif27 ss = (struct sockaddr_storage*)((char*)ss + salen);28 }29 }Последовательная обработка адресовФункция перебирает адреса в цикле. Общее количество адресов указывается вызывающим процессом.7-8Вывод адресаАдрес преобразуется к удобочитаемому виду функцией9, которая, как вы помните, должна работать со структурами адреса сокета всех форматов, поддерживаемых системой.sock_ntopОпределение размера адресаСписок адресов передается в упакованном формате. Это не просто массив структур s10-26. Дело в том, что структураockaddr_storageдостаточно велика, и ее нецелесообразно использовать при передаче адресов между ядром и пользовательскими процессами. В системах, где эта структура содержит внутреннее поле длины, обработка списка является делом тривиальным: достаточно извлекать длину из текущей структурыsockaddr_storage. В прочих системах длина определяется на основании семейства адреса. Если семейство не определено, функция завершает работу с сообщением об ошибке.sockaddr_storageПеремещение указателяК указателю на элемент списка прибавляется размер адреса. Таким образом осуществляется перемещение по списку адресов.27Выполнение программы
Результат взаимодействия модифицированного клиента с сервером представлен ниже.
FreeBSD-lap: <b>./sctpclient01 10.1.1.5</b><b>[0]Hi</b>There are 2 remote addresses and they are:10.1.1.5:9877127.0.0.1:9877There are 2 local addresses and they are:10.1.1.5:1025127.0.0.1:1025From str:0 seq:0 (assoc:c99e2680):[0]Hi<b>Control-D</b>FreeBSD-lap:23.8. Определение идентификатора ассоциации по IP-адресу
Модифицированный клиент из раздела 23.7 использовал уведомления в качестве сигнала для получения списков адресов. Это было достаточно удобно, поскольку идентификатор ассоциации, для которой требовалось получить адреса, содержался в уведомлении в поле
. Но что если приложение не отслеживает идентификаторы ассоциаций, а ему вдруг понадобилось определить какой- либо идентификатор по адресу собеседника? В листинге 23.13 представлена простая функция, преобразующая адрес собеседника в идентификатор ассоциации. Эта функция будет использоваться сервером из раздела 23.10.sac_assoc_idЛистинг 23.13. Преобразование адреса в идентификатор ассоциации
//sctp/sctp_addr_to_associd.с1 #include "unp.h"2 sctp_assoc_t3 sctp_address_to_associd(int sock_fd, struct sockaddr *sa, socklen_t salen)