Вход/Регистрация
Операционная система UNIX
вернуться

Робачевский Андрей Михайлович

Шрифт:

confirm.maxlen =

sizeof(struct T_conn_con) + addr.maxlen + opt.maxlen;

buf = (char*)malloc(confirm.maxlen);

confirm.buf = buf;

m_data.len = udata.len;

m_data.maxlen = udata.maxlen;

m_data.buf = udata.buf;

/* Получим примитив T_CONN_CON */

getmsg(fd, &confirm, &m_data, &flags);

free(buf);

conncon = (struct T_conn_con*)confirm.buf;

if (conncon->PRIM_type == T_CONN_CON) {

/* Если это действительно согласие, заполним

структуру rcvcall для пользователя TLI */

addr.len = conncon->OPT_length;

opt.len = conncon->OPT_length;

memcpy(addr.buf, conncon+conncon->RES_offset, addr.len);

memcpy(opt.buf, conncon+conncon->OPT_offset, opt.len);

free(confirm.buf);

/* Все закончилось удачно — возвращаем 0 */

return 0;

}

} else {

/* В случае отказа мы готовы обработать примитив

T_DISCON_IND */

...

return -1;

}

 } else {

/* Если получен примитив T_ERROR_ACK — обработаем его */

errack = (struct T_error_ack*)ack.buf;

...

return -1;

 }

}

Подобным образом реализовано большинство функций TLI. Заметим, что в конкретном случае использования транспортного протокола TCP прием и передача данных осуществляются в виде потока, не содержащего каких-либо логических записей. В этом случае не требуется формирование примитивов типа

T_DATA_REQ
и
T_DATA_IND
. В то же время, для передачи и получения экстренных данных будут использованы примитивы
T_EXDATA_REQ
и
T_EXDATA_IND
. При использовании протокола UDP все данные будут передаваться с помощью примитивов
T_UNITDATA_REQ
и
T_UNITDATA_IND
.

Описанная реализация программного интерфейса TLI имеет один существенный недостаток — операции функций не являются атомарными. Другими словами, выполнение функции t_connect(3N) может быть прервано другими процессами, которые могут также связываться с удаленным узлом. Это возможно, поскольку выполнение значительной части операций происходит в режиме задачи. Если для функции t_connect(3N) нарушение атомарности допустимо, то ряд функций, таких, например, как связывание (t_bind(3N)), получение информации (t_open(3N), t_getinfo(3N)) и установка или получение опций протокола (t_optmgmt(3N)) должны быть защищены от возможного нарушения целостности данных по причине прерывания операции. Единственным способом гарантировать атомарность является перевод выполнения критических участков (например, между отправлением примитива и получением подтверждения от поставщика транспортных услуг) в режим ядра. Для этого подсистема STREAMS предлагает механизм обмена управляющими командами с помощью вызова ioctl(2).

Однако с помощью ioctl(2), как было показано в разделе "Подсистема STREAMS" главы 5, можно формировать лишь сообщения типа

M_IOCTL
. Для преобразования этих сообщений в примитивы TPI служит дополнительный модуль timod(7M), встраиваемый в поток между головным и транспортным модулями. На рис. 6.33 показано местоположение модуля timod(7M) и схематически отображены его функции.

Рис. 6.33. Архитектура доступа к транспортным услугам

Для всех сообщений STREAMS, за исключением сообщений

M_IOCTL
, которые генерируются головным модулем в ответ на системный вызов
ioctl(fd, I_STR, ...)
, модуль timod(7M) является прозрачным, т.е. он просто передает эти сообщения следующему модулю вниз по потоку без какой-либо обработки. Несколько сообщений
M_IOCTL
обрабатываются модулем и преобразуются в соответствующие примитивы TPI.

При этом вызов ioctl(2) имеет следующий формат:

#include <sys/stropts.h>

struct strioctl my_strioctl

...

strioctl.ic_cmd = cmd;

strioctl.ic_timeout = INFTIM;

strioctl.ic_len = size;

strioctl.ic_dp = (char*)buf;

ioctl(fd, I_STR, &my_strioctl);

При вызове ioctl(2) поле

size
устанавливается равным размеру соответствующего примитива TPI, определенного полем
cmd
и расположенного в буфере
buf
. При возврате из функции поле
size
содержит размер примитива, возвращенного поставщиком транспортных услуг и расположенного в буфере buf.

  • Читать дальше
  • 1
  • ...
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • ...

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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