Вход/Регистрация
UNIX: разработка сетевых приложений
вернуться

Стивенс Уильям Ричард

Шрифт:

24 ctlbuf.maxlen = sizeof(bind_ack);

25 ctlbuf.len = 0;

26 ctlbuf.buf = (char*)&bind_ack;

27 flags = RS_HIPRI;

28 Getmsg(fd, &ctlbuf, NULL, &flags);

29 if (ctlbuf.len < (int)sizeof(long))

30 err_quit("bad length from getmsg");

31 switch (bind_ack.msg_hdr.PRIM_type) {

32 case T_BIND_ACK:

33 return;

34 case T_ERROR_ACK:

35 if (ctlbuf.len < (int)sizeof(struct T_error_ack))

36 err_quit("bad length for T_ERROR_ACK");

37 error_ack = (struct T_error_ack*)&bind_ack.msg_hdr;

38 err_quit("T_ERROR_ACK from bind (%d, %d)",

39 error_ack->TLI_error, error_ack->UNIX_error);

40 default:

41 err_quit("unexpected message type: %d", bind_ack.msg_hdr.PRlM_type);

42 }

43 }

Заполнение структуры T_bind_req

16-20
Заголовочный файл
<sys/tihdr.h>
определяет структуру
T_bind_req
:

struct T_bind_req {

long PRIM_type; /* T_BIND_REQ */

long ADDR_length; /* длина адреса */

long ADDR_offset; /* смещение адреса */

unsigned long CONIND_number; /* сообщения о соединении */

/* далее следует адрес протокола для связывания */

};

Все запросы TPI определяются как структуры, начинающиеся с поля типа

long
. Мы определяем свою собственную структуру
bind_req
, начинающуюся со структуры
T_bind_req
, после которой располагается буфер, содержащий локальный адрес для связывания. TPI ничего не говорит о содержимом буфера — оно определяется поставщиком. Поставщик TCP предполагает, что этот буфер содержит структуру
sockaddr_in
.

Мы заполняем структуру

T_bind_req
, устанавливая элемент
ADDR
_length равным размеру адреса (16 байт для структуры адреса сокета Интернета), а элемент
ADDR_offset
— равным байтовому сдвигу адреса (он следует непосредственно за структурой
T_bind_req
). У нас нет гарантии, что это местоположение соответствующим образом выровнено для записи структуры
sockaddr_in
, поэтому мы вызываем функцию
memcpy
, чтобы скопировать структуру вызывающего процесса в нашу структуру
bind_req
. Мы присваиваем элементу
CONIND_number
нулевое значение, потому что мы находимся на стороне клиента, а не на стороне сервера.

Вызов функции putmsg

21-23
TPI требует, чтобы только что созданная нами структура была передана поставщику как одно сообщение
M_PROTO
. Следовательно, мы вызываем функцию
putmsg
, задавая структуру
bind_req
в качестве управляющей информации, без каких-либо данных и с флагом 0.

Вызов функции getmsg для чтения сообщений с высоким приоритетом

24-30
Ответом на наш запрос
T_BIND_REQ
будет либо сообщение
T_BIND_ACK
, либо сообщение
T_ERROR_ACK
. Сообщения, содержащие подтверждение, отправляются как сообщения с высоким приоритетом (
M_PCPROTO
), так что мы считываем их при помощи функции
getmsg
с флагом
RS_HIPRI
. Поскольку ответ является сообщением с высоким приоритетом, он получает преимущество перед всеми обычными сообщениями в потоке.

Эти два сообщения выглядят следующим образом:

struct T_bind_ack {

long PRIM_type; /* T_BIND_ACK */

long ADDR_length; /* длина адреса */

long ADDR_offset; /* смещение адреса */

unsigned long CONIND_number; /* индекс подключения для помещения

в очередь */

};

/* затем следует связанный адрес */

struct T_error_ack {

long PRIM_type; /* T_ERROR_ACK */

long ERROR_prim; /* примитивная ошибка ввода */

  • Читать дальше
  • 1
  • ...
  • 454
  • 455
  • 456
  • 457
  • 458
  • 459
  • 460
  • 461
  • 462
  • 463
  • 464
  • ...

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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