KnigaRead.com/
KnigaRead.com » Компьютеры и Интернет » Программное обеспечение » Уильям Стивенс - UNIX: разработка сетевых приложений

Уильям Стивенс - UNIX: разработка сетевых приложений

На нашем сайте KnigaRead.com Вы можете абсолютно бесплатно читать книгу онлайн Уильям Стивенс, "UNIX: разработка сетевых приложений" бесплатно, без регистрации.
Перейти на страницу:

#include <netinet/sctp.h>


int sctp_bindx(int sockfd, const struct sockaddr *addrs, int addrcnt, int flags);

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

Аргумент sockfd представляет собой дескриптор сокета, возвращаемый функцией socket. Второй аргумент — указатель на упакованный список адресов. Каждая структура адреса сокета помещается в буфер непосредственно после предшествующей структуры, без всяких дополняющих нулей (пример приводится на рис. 9.3).

Рис. 9.3. Формат упакованного списка адресов для функций SCTP

Количество адресов, передаваемых sctp_bindx, указывается в параметре addrcnt. Параметр flags сообщает функции sctp_bindx о необходимости выполнения действий, перечисленных в табл. 9.1.


Таблица 9.1. Флаги функции sctp_bindx

Значение аргумента flags Описание SCTP_BINDX_ADD_ADDR Добавляет адреса к уже определенным для сокета SCTP_BINDX_REM_ADDR Удаляет адреса из списка адресов сокета

Функцию sctp_bindx можно вызывать независимо от того, привязан ли сокет к каким-нибудь адресам. Для несвязанного сокета вызов sctp_bindx приведет к привязке указанного набора адресов. При работе с уже связанным сокетом указание флага SCTP_BINDX_ADD_ADDR позволяет добавить адреса к данному дескриптору. Флаг SCTP_BINDX_REM_ADDR предназначен для удаления адресов из списка связанных с данным дескриптором. Если sctp_bindx вызывается для прослушиваемого сокета, новая конфигурация будет использоваться только для новых ассоциаций; вызов никак не затронет уже установленные ассоциации. Флаги sctp_bindx взаимно исключают друг друга: если указать оба, функция вернет ошибку EINVAL. Номер порта во всех структурах адреса сокета должен быть одним и тем же. Он должен совпадать с тем номером порта, который был связан с данным сокетом ранее. В противном случае sctp_bindx тоже вернет ошибку EINVAL.

Если конечная точка поддерживает динамическую адресацию, вызов sctp_bindx с флагом SCTP_BINDX_REM_ADDR или SCTP_BINDX_ADD_ADDR приведет к передаче собеседнику сообщения о необходимости изменения списка адресов. Поскольку изменение списка адресов для установленной ассоциации не является обязательным, реализации, не поддерживающие эту функцию, будут при попытке ее использования возвращать ошибку EOPNOTSUPP. Обратите внимание, что для нормальной работы динамической адресации она должна поддерживаться обеими сторонами. Все это полезно в том случае, если система поддерживает динамическое предоставление интерфейсов: когда открывается доступ к новому интерфейсу Ethernet, приложение может вызвать SCTP_BINDX_ADD_ADDR и начать работать с этим интерфейсом по уже установленным ассоциациям.

9.4. Функция sctp_connectx

#include <netinet/sctp.h>


int sctp_connectx(int sockfd, const struct sockaddr *addrs, int addrcnt);

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

Функция sctp_connectx используется для соединения с многоинтерфейсным узлом. При ее вызове мы должны указать адреса собеседника в параметре addrs (количество адресов определяется параметром addrcnt). Формат структуры addrs представлен на рис. 9.3. Стек SCTP устанавливает ассоциацию, используя один или несколько адресов из переданного списка. Все адреса addrs считаются действующими и подтвержденными.

9.5. Функция sctp_getpaddrs

Функция getpeername не предназначена для использования протоколом, рассчитанным на работу с многоинтерфейсными узлами. Для сокетов SCTP она способна вернуть лишь основной адрес собеседника. Если нужны все адреса, следует вызывать функцию sctp_getpaddrs.

#include <netinet/sctp.h>


int sctp_getpaddrs(int sockfd, sctp_assoc_t id, struct sockadrrd **addrs);

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

Аргумент sockfd представляет собой дескриптор сокета, возвращаемый функцией socket. Второй аргумент задает идентификатор ассоциации для сокетов типа «один-ко-многим». Для сокетов типа «один-к-одному» этот аргумент игнорируется. addrs — адрес указателя, который функция sctp_getpaddrs заполнит упакованным списком адресов, выделив под него локальный буфер (см. рис. 9.3 и листинг 23.12). Для освобождения буфера, созданного sctp_getpaddrs, следует использовать вызов sctp_freepaddrs.

9.6. Функция sctp_freepaddrs

Функция sctp_freepaddrs освобождает ресурсы, выделенные вызовом sctp_getpaddrs.

#include <netinet/sctp.h>


void sctp_freepaddrs(struct sockaddr *addrs);

Здесь аргумент addrs — указатель на массив адресов, возвращаемый sctp_getpaddrs.

9.7. Функция sctp_getladdrs

Функция sctp_getladdrs может использоваться для получения списка локальных адресов, относящихся к определенной ассоциации. Эта функция бывает необходима в тех случаях, когда приложению требуется узнать, какие именно локальные адреса оно использует (набор адресов, напомним, может быть произвольным подмножеством всех адресов системы).

#include <netinet/sctp.h>


int sctp_getladdrs(int sockfd, sctp_assoc_t id, struct sockaddr **addrs);

Возвращает: количество локальных адресов, помещенных в addrs, или -1 в случае ошибки.

Здесь sockfd — дескриптор сокета, возвращаемый функцией socket. Аргумент id — идентификатор ассоциации для сокетов типа «один-ко-многим». Поле id игнорируется для сокетов типа «один-к-одному». Параметр представляет собой адрес указателя на буфер, выделяемый и заполняемый функцией sctp_getladdrs. В этот буфер помещается упакованный список адресов. Структура списка представлена на рис. 9.3 и в листинге 23.12. Для освобождения буфера процесс должен вызвать функцию sctp_freeladdrs.

9.8. Функция sctp_freeladdrs

Функция sctp_freeladdrs освобождает ресурсы, выделенные при вызове sctp_getladdrs.

#include <netinet/sctp.h>


void sctp_freeladdrs(struct sockaddr *addrs);

Здесь addrs указывает на список адресов, возвращаемый sctp_getladdrs.

9.9. Функция sctp_sendmsg

Приложение может управлять параметрами SCTP, используя функцию sendmsg со вспомогательными данными (см. главу 14). Однако из-за неудобств, связанных с применением вспомогательных данных, многие реализации SCTP предоставляют дополнительный библиотечный вызов (который на самом деле может быть и системным вызовом), упрощающий обращение к расширенным функциям SCTP. Вызов функции должен иметь следующий формат:

ssize_t sctp_sendmsg(int sockfd, const void *msg, size_t msgsz,

 const struct sockaddr *to, socklen_t tolen, uint32_t ppid,

 uint32_t flags, uint16_t stream, uint32_t timetolive,

 uint32_t context);

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

Использование sctp_sendmsg значительно упрощает отправку параметров, но требует указания большего количества аргументов. В поле sockfd помещается дескриптор сокета, возвращенный системным вызовом socket. Аргумент msg указывает на буфер размера msgsz, содержимое которого должно быть передано собеседнику. В поле tolen помещается длина адреса, передаваемого через аргумент to. В поле ppid помещается идентификатор протокола, который будет передан вместе с порцией данных. Поле flags передается стеку SCTP. Разрешенные значения этого поля приводятся в табл. 7.5.

Номер потока SCTP указывается вызывающим приложением в аргументе stream. Процесс может указать время жизни сообщения в миллисекундах в поле lifetime. Значение 0 соответствует бесконечному времени жизни. Пользовательский контекст, при наличии такового, может быть указан в поле context. Пользовательский контекст связывает неудачную передачу сообщения (о которой получено уведомление) с локальным контекстом, имеющим отношение к приложению. Например, чтобы отправить сообщение в поток 1 с флагом отправки MSG_PR_SCTP_TTL, временем жизни равным 1000 мс, идентификатором протокола 24 и контекстом 52, процесс должен сделать следующий вызов:

ret =

 sctp_sendmsg(sockfd, data, datasz, &dest, sizeof(dest), 24,

  MSG_PR_SCTP_TTL, 1, 1000, 52);

Этот подход значительно проще выделения памяти под необходимые вспомогательные данные и настройки структур, входящих в msghdr. Обратите внимание, что если функция sctp_sendmsg реализована через вызов sendmsg, то поле flags в последнем устанавливается равным 0.

Перейти на страницу:
Прокомментировать
Подтвердите что вы не робот:*