-->

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

На нашем литературном портале можно бесплатно читать книгу UNIX: разработка сетевых приложений, Стивенс Уильям Ричард-- . Жанр: ОС и Сети. Онлайн библиотека дает возможность прочитать весь текст и даже без регистрации и СМС подтверждения на нашем литературном портале bazaknig.info.
UNIX: разработка сетевых приложений
Название: UNIX: разработка сетевых приложений
Дата добавления: 16 январь 2020
Количество просмотров: 386
Читать онлайн

UNIX: разработка сетевых приложений читать книгу онлайн

UNIX: разработка сетевых приложений - читать бесплатно онлайн , автор Стивенс Уильям Ричард

Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.

Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала

Перейти на страницу:
Инициализация при первом вызове

20-24
 При первом вызове нашей функции мы вызываем функцию
rtt_init
.

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

25-41
 Мы заполняем две структуры
msghdr
, используемые для ввода и вывода. Для данного пакета мы увеличиваем на единицу порядковый номер отправки, но не устанавливаем отметку времени отправки, пока пакет не будет отправлен (поскольку он может отправляться повторно, а для каждой повторной передачи требуется текущая отметка времени).

Вторая часть функции вместе с обработчиком сигнала

sig_alarm
показана в листинге 22.7.

Листинг 22.7. Функция dg_send_recv: вторая половина

//rtt/dg_send_rеcv.c

42  Signal(SIGALRM, sig_alrm);

43  rtt_newpack(&rttinfo); /* инициализируем для этого пакета */

44 sendagain:

45  sendhdr.ts = rtt_ts(&rttinfo);

46  Sendmsg(fd, &msgsend, 0);

47  alarm(rtt_start(&rttinfo)); /* вычисляем тайм-аут. запускаем таймер */

48  if (sigsetjmp(jmpbuf, 1) != 0) {

49   if (rtt_timeout(&rttinfо) < 0) {

50    err_msg("dg_send_recv: no response from server, giving up");

51    rttinit = 0; /* повторная инициализация для следующего вызова */

52    errno = ETIMEDOUT;

53    return (-1);

54   }

55   goto sendagain;

56  }

57  do {

58   n = Recvmsg(fd, &msgrecv, 0);

59  } while (n < sizeof(struct hdr) || recvhdr.seq != sendhdr.seq);

60  alarm(0); /* останавливаем таймер SIGALRM */

61  /* вычисляем и записываем новое значение оценки RTT */

62  rtt_stop(&rttinfo, rtt_ts(&rttinfo) — recvhdr.ts);

63  return (n - sizeof(struct hdr)); /* возвращаем размер полученной

                                        дейтаграммы */

64 }

65 static void

66 sig_alrm(int signo)

67 {

68  siglongjmp(jmpbuf, 1);

69 }

Установка обработчика сигналов

42-43
 Для сигнала
SIGALRM
устанавливается обработчик сигналов, а функция
rtt_newpack
устанавливает счетчик повторных передач в нуль.

Отправка дейтаграммы

45-47
 Функция
rtt_ts
получает текущую отметку времени. Отметка времени хранится в структуре
hdr
, которая добавляется к данным пользователя. Одиночная дейтаграмма UDP отправляется функцией
sendmsg
. Функция
rtt_start
возвращает количество секунд для этого тайм-аута, а сигнал
SIGALRM
контролируется функцией
alarm
.

Установка буфера перехода

48
 Мы устанавливаем буфер перехода для нашего обработчика сигналов с помощью функции sigsetjmp. Мы ждем прихода следующей дейтаграммы, вызывая функцию
recvmsg
. (Совместное использование функций
sigsetjmp
и
siglongjmp
вместе с сигналом
SIGALRM
мы обсуждали применительно к листингу 20.5.) Если время таймера истекает, функция
sigsetjmp
возвращает 1.

Обработка тайм-аута

49-55
 Когда возникает тайм-аут, функция
rtt_timeout
вычисляет следующее значение RTO (используя экспоненциальное смещение) и возвращает -1, если нужно прекратить попытки передачи дейтаграммы, или 0, если нужно выполнить очередную повторную передачу. Когда мы прекращаем попытки, мы присваиваем переменной
errno
значение
ETIMEDOUT
и возвращаемся в вызывающую функцию.

Вызов функции recvmsg, сравнение порядковых номеров

57-59
 Мы ждем прихода дейтаграммы, вызывая функцию
recvmsg
. Длина полученной дейтаграммы не должна быть меньше размера структуры
hdr
, а ее порядковый номер должен совпадать с порядковым номером запроса, ответом на который предположительно является эта дейтаграмма. Если при сравнении хотя бы одно из этих условий не выполняется, функция
recvmsg
вызывается снова.

Выключение таймера и обновление показателей RTT

60-62
 Когда приходит ожидаемый ответ, функция
alarm
отключается, а функция
rtt_stop
обновляет оценочное значение RTT. Функция
rtt_ts
возвращает текущую отметку времени, и отметка времени из полученной дейтаграммы вычитается из текущей отметки, что дает в результате RTT.

Обработчик сигнала SIGALRM

65-69
Вызывается функция
siglongjmp
, результатом выполнения которой является то, что функция
sigsetjmp
в
dg_send_recv
возвращает 1.

Теперь мы рассмотрим различные функции RTT, которые вызывались нашей функцией

dg_send_recv
. В листинге 22.8 показан заголовочный файл
unprtt.h
.

Листинг 22.8. Заголовочный файл unprtt.h

//lib/unprtt.h

 1 #ifndef __unp_rtt_h

 2 #define __unp_rtt_h

 3 #include "unp.h"

 4 struct rtt_info {

Перейти на страницу:
Комментариев (0)
название