if (okack-PRIM_type == T_OK_ACK) {
/* Если подтверждение положительное, подготовимся к получению
согласия удаленного пользователя на установление связи
(примитив T_CONN_CON) */
free(ack.buf);
if (recvcall != NULL) {
addr = recvcall-addr;
opt = recvcall-opt;
udata = recvcall-udata;
confirm.len = sizeof(struct T_conn_con) + addr.len + opt.len;
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 имеет один существенный недостаток — операции функций не являются атомарными. Другими словами, выполнение функции
Однако с помощью M_IOCTL
. Для преобразования этих сообщений в примитивы TPI служит дополнительный модуль
Рис. 6.33. Архитектура доступа к транспортным услугам
Для всех сообщений STREAMS, за исключением сообщений M_IOCTL
, которые генерируются головным модулем в ответ на системный вызов ioctl(fd, I_STR, ...)
, модуль M_IOCTL
обрабатываются модулем и преобразуются в соответствующие примитивы TPI.