Литмир - Электронная Библиотека
Содержание  
A
A

■ При создании сокета библиотекой сокетов в поток помещается модуль

sockmod
. Именно комбинация библиотеки сокетов и потокового модуля обеспечивает API сокетов для процесса.

■ При создании точки доступа XTI библиотекой XTI в поток помещается модуль

timod
. Именно комбинация библиотеки XTI и потокового модуля обеспечивает API XTI для процесса.

ПРИМЕЧАНИЕ

Это одно из немногих мест, где мы говорим об XTI. Предыдущее издание этой книги описывало интерфейс XTI очень подробно, но он уже вышел из широкого употребления, и даже спецификация POSIX больше не включает его, поэтому мы решили исключить ставшие ненужными главы из книги. На рис. 31.3 показано, каким образом обычно реализуется интерфейс XTI. В этой главе мы кратко расскажем о нем, но не будем вдаваться в подробности, потому что причин для использования XTI в настоящее время практически нет.

■ Для использования функций

read
или
write
в точке доступа XTI требуется поместить в поток потоковый модуль
tirdwr
. Это осуществляется процессом, использующим TCP, который на рис. 31.3 изображен четвертым слева. Вероятно, этот процесс тем самым отказался от использования XTI, поэтому мы убрали надпись «библиотека XTI» из соответствующего блока.

■ Формат сетевых сообщений, передаваемых по потокам вверх и вниз, определяют интерфейсы различных сервисов. Мы описываем три наиболее широко распространенных. TPI (Transport Provider Interface — интерфейс поставщика транспортных служб) [126] определяет интерфейс, предоставляемый поставщиком услуг транспортного уровня (например, TCP или UDP). NPI (Network Provider Interface — интерфейс поставщика сетевого уровня) [125] определяет интерфейс, предоставляемый поставщиком услуг сетевого уровня (например, IP). DLPI (Data Link Provider Interface) — это интерфейс поставщика канального уровня [124]. Еще один источник информации по TPI и DLPI, в котором имеются также исходные коды на языке С, — это [98].

Каждый компонент потока — головной модуль, все модули обработки и драйвер — содержат по меньшей мере одну пару очередей: очередь на запись и очередь на чтение. Это показано на рис. 31.4.

UNIX: разработка сетевых приложений - img_167.png

Рис. 31.4. Каждый компонент потока содержит по меньшей мере одну пару очередей

Типы сообщений

Потоковые сообщения могут быть классифицированы как имеющие высокий приоритет (high priority), входящие в полосу приоритета (priority band) и обычные (normal). Существует 256 полос приоритета со значениями между 0 и 255, причем обычные сообщения соответствуют полосе 0. Приоритет потокового сообщения используется как при постановке сообщения в очередь, так и для управления потоком (flow control). По соглашению, на сообщения с высоким приоритетом управление потоком не влияет.

На рис. 31.5 показан порядок следования сообщений в одной конкретной очереди.

UNIX: разработка сетевых приложений - img_168.png

Рис. 31.5. Порядок следования потоковых сообщений в очереди в зависимости от их приоритета

Хотя потоковые системы поддерживают 256 различных полос приоритета, в сетевых протоколах обычно используется полоса 1 для срочных (внеполосных) данных и полоса 0 для обычных данных.

ПРИМЕЧАНИЕ

Внеполосные данные TCP в TPI не рассматриваются как истинные срочные данные. В самом деле, в TCP полоса 0 используется как для обычных, так и для внеполосных данных. Полоса 1 используется для отправки срочных данных в тех протоколах, в которых срочные данные (а не просто срочный указатель, как в TCP) отправляются перед обычными данными. В данном контексте следует внимательно отнестись к термину «обычный» (normal). В системах SVR, предшествующих SVR4, не было полос приоритета, а сообщения делились на обычные и приоритетные (priority messages). В SVR4 были введены полосы приоритета, что потребовало также введения функций getpmsg и putpmsg, которые мы вскоре опишем. Приоритетные сообщения были переименованы в сообщения с высоким приоритетом, и встал вопрос, как называть сообщения, относящиеся к полосам приоритета от 1 до 255. Наиболее распространенной является терминология [98], согласно которой все сообщения, которые не являются сообщениями с высоким приоритетом, называются обычными сообщениями и разделяются на подкатегории согласно своим полосам приоритета. Термин «обычное сообщение» в любом случае должен соответствовать сообщению из полосы приоритета 0.

Хотя пока мы говорили только о сообщениях с высоким приоритетом и об обычных сообщениях, существует около 12 типов обычных сообщений и около 18 типов сообщений с высоким приоритетом. С точки зрения приложений и функций

getmsg
и
putmsg
, которые мы опишем в следующем разделе, нам интересны только три различных типа сообщений:
M_DATA
,
M_PROTO
и
M_PCPROTO
(
PC
означает «priority control», то есть приоритетное управление, и подразумевает сообщения с высоким приоритетом). В табл. 31.1 показано, как эти три типа сообщений генерируются функциями
write
и
putmsg
.

Таблица 31.1. Типы потоковых сообщений, генерируемые функциями write и putmsg

Функция Управляющая информация? Данные? Флаги Генерируемый тип сообщения
write Да M_DATA
putmsg Нет Да 0 M_DATA
putmsg Да Все равно 0 M_PROTO
putmsg Да Все равно MSG_HIPRI M_PCPROTO

31.3. Функции getmsg и putmsg

Данные, передаваемые в обоих направлениях по потоку, состоят из сообщений, а каждое сообщение содержит данные, управляющую информацию или и то и другое. Если мы используем функции

read
или
write
, то мы можем передавать только данные. Для того чтобы процесс мог записывать и считывать как данные, так и управляющую информацию, необходимо добавить две новые функции.

#include <stropts.h>

int getmsg(int <i>fd</i>, struct strbuf *<i>ctlptr</i>, struct strbuf *<i>dataptr</i>, int *<i>flagsp</i>);

int putmsg(int <i>fd</i>, const struct strbuf *<i>ctlptr</i>,

359
{"b":"225366","o":1}