Другой тип клиента, для которого нежелательно использование алгоритма Нагла и задержанных ACK TCP, — это клиент, отправляющий одиночный логический запрос своему серверу небольшими порциями. Например, будем считать, что клиент отправляет своему серверу 400-байтовый запрос, состоящий из 4 байт, задающих тип запроса, за которыми следуют 396 байт данных. Если клиент выполняет функцию write
write
, отправляя остальные 396 байт, вторая часть не будет отправлена со стороны клиента, пока TCP сервера не подтвердит получение первых 4 байт. Кроме того, поскольку сервер не может работать с 4 байтами данных, пока не получит оставшиеся 396 байт, TCP сервера задержит сегмент ACK, подтверждающий получение 4 байт данных (то есть не будет данных от сервера клиенту, в которые можно вложить сегмент ACK). Есть три способа решить проблему с таким клиентом.1. Использовать функцию writev
write
. Один вызов функции writev
приводит к отправке только одного сегмента TCP в нашем примере. Это предпочтительное решение.2. Скопировать 4 байт и 396 байт данных в один буфер и вызвать один раз функцию write
3. Установить параметр сокета TCP_NODELAY
write
дважды. Это наименее желательное решение.Упражнения 7.8 и 7.9 продолжают этот пример.
7.10. Параметры сокетов SCTP
Относительно большое количество параметров, определенных для сокетов SCTP (17 на момент написания этой книги), дают возможность разработчику приложения более точно контролировать его поведение. Параметр level
IPPROTO_SCTP
.Несколько параметров, используемых для получения сведений об SCTP, требуют передачи данных ядру (например, идентификатора ассоциации или адреса собеседника). Не все реализации getsockopt
sctp_opt_info
(раздел 9.11), которая устраняет эту проблему. В некоторых системах, где getsockopt
поддерживает передачу данных в ядро, функция sctp_opt_info
является не более, чем оболочкой для getsockopt
. В других системах она может вызывать функцию ioctl
или какую-либо иную, возможно, созданную специально для данного случая. Мы рекомендуем получать параметры сокетов SCTP при помощи sctp_opt_info
, так как в этом случае обеспечивается максимальная переносимость. В табл. 7.2 соответствующие параметры отмечены знаком «+
»: SCTP_ASSOCINFO
, SCTP_GET_PEER_ADDR_INFO
, SCTP_PEER_ADDR_PARAMS
, SCTP_PRIMARY_ADDR
, SCTP_RTOINFO
и SCTP_STATUS
.Параметр сокета SCTP_ADAPTION_LAYER
При инициализации ассоциации любой собеседник может указать на наличие уровня-адаптора. Это указание должно представлять из себя 32-разрядное беззнаковое целое, которое может использоваться двумя приложениями для координации локального уровня-адаптора приложений. Параметр сокета позволяет получать или устанавливать указание на наличие уровня-адаптора, которое будет предоставляться данной конечной точкой будущим собеседникам. Чтобы получить соответствующее значение, установленное собеседником, приложение должно подписаться на события уровня-адаптора.
Параметр сокета SCTP_ASSOCINFO
Параметр сокета SCTP_ASSOCINFO
getsockopt
следует использовать sctp_opt_info
. Вместе с параметром при вызове функции указывается структура sctp_assocparams
:struct sctp_assocparams {
sctp_assoc_t sasoc_assoc_id;
uint16_t sasoc_asocmaxrxt;
uint16_t sasoc_number_peer_destinations;
uint32_t sasoc_peer_rwnd;
uint32_t sasoc_local_rwnd;
uint32_t sasoc_cookie_life;
};
Поля структуры имеют следующий смысл:
■ sasoc_assoc_id
setsockopt
параметр установлен в нуль, поля sasoc_asocmaxrxt
и sasoc_cookie_life
трактуются как новые значения по умолчанию для сокета. Вызов getsockopt
вернет сведения об ассоциации, если при вызове указать ее идентификатор; если же поле оставить нулевым, будут возвращены значения по умолчанию;