UNIX: разработка сетевых приложений
Шрифт:
Листинг 22.9. Макрос RTT_RTOCALC, функции rtt_minmax и rtt_init
//lib/rtt.c
1 #include "unprtt.h"
2 int rtt_d_flag = 0; /* отладочный флаг; может быть установлен в
ненулевое значение вызывающим процессом */
3 /* Вычисление значения RTO на основе текущих значений:
4 * сглаженное оценочное значение RTT + четырежды сглаженная
5 * величина
отклонения.
6 */
7 #define RTI_RTOCALC(ptr) ((ptr)->rtt_srtt + (4.0 * (ptr)->rtt_rttvar))
8 static float
9 rtt_minmax(float rto)
10 {
11 if (rto < RTT_RXTMIN)
12 rto = RTT_RXTMIN;
13 else if (rto > RTT_RXTMAX)
14 rto = RTT_RXTMAX;
15 return (rto);
16 }
17 void
18 rtt_init(struct rtt_info *ptr)
19 {
20 struct timeval tv;
21 Gettimeofday(&tv, NULL);
22 ptr->rtt_base = tv.tv_sec; /* количество секунд, прошедших с 1.1.1970 */
23 ptr->rtt_rtt = 0;
24 ptr->rtt_srtt = 0;
25 ptr->rtt_rttvar = 0.75;
26 ptr->rtt_rto = rtt_minmax(RTT_RTOCALC(ptr));
27 /* первое RTO (srtt + (4 * rttvar)) = 3 с */
28 }
3-7
Макрос вычисляет RTO как сумму оценочной величины RTT и оценочной величины среднего отклонения, умноженной на четыре.
8-16
Функция rtt_minmax
проверяет, что RTO находится между верхним и нижним пределами, заданными в заголовочном файле unprtt.h
.
17-28
Функция rtt_init
вызывается функцией dg_send_recv
при первой отправке пакета. Функция gettimeofday
возвращает текущее время и дату в той же структуре timeval
, которую мы видели в функции select
(см. раздел 6.3). Мы сохраняем только текущее количество секунд с момента начала эпохи Unix, то есть с 00:00:00 1 января 1970 года (UTC). Измеряемое значение RTT обнуляется, а сглаженная оценка RTT и среднее отклонение принимают соответственно значение 0 и 0,75, в результате чего начальное RTO равно 3 с (4x0,75). В листинге 22.10 показаны следующие три функции RTT.
Листинг 22.10. Функции rtt_ts, rtt_newpack и rtt_start
//lib/rtt.c
34 uint32_t
35 rtt_ts(struct rtt_info *ptr)
36 {
37 uint32_t ts;
38 struct timeval tv;
39 Gettimeofday(&tv, NULL);
40 ts = ((tv.tv_sec - ptr->rtt_base) * 1000) + (tv.tv_usec / 1000);
41 return (ts);
42 }
43 void
44 rtt_newpack(struct rtt_info *ptr)
45 {
46 ptr->rtt_nrexmt = 0;
47 }
48 int
49 rtt_start(struct rtt_info *ptr)
50 {
51 return ((int)(ptr->rtt_rto + 0.5)); /*
округляем float до int */
52 /* возвращенное значение может быть использовано как аргумент
alarm(rtt_start(&fоо)) */
53 }
34-42
Функция rtt_ts
возвращает текущую отметку времени для вызывающего процесса, которая должна содержаться в отправляемой дейтаграмме в виде 32-разрядного целого числа без знака. Мы получаем текущее время и дату из функции gettimeofday
и затем вычитаем число секунд в момент вызова функции rtt_init
(значение, хранящееся в элементе rtt_base
структуры rtt_info
). Мы преобразуем это значение в миллисекунды, а также преобразуем в миллисекунды значение, возвращаемое функцией gettimeofday
в микросекундах. Тогда отметка времени является суммой этих двух значений в миллисекундах. Разница во времени между двумя вызовами функции
rtt_ts
представляется количеством миллисекунд между этими двумя вызовами. Но мы храним отметки времени в 32-разрядном целом числе без знака, а не в структуре timeval
.
43-47
Функция rtt_newpack
просто обнуляет счетчик повторных передач. Эта функция должна вызываться всегда, когда новый пакет отправляется в первый раз.
48-53
Функция rtt_start
возвращает текущее значение RTO в миллисекундах. Возвращаемое значение затем может использоваться в качестве аргумента функции alarm
. Функция
rtt_stop
, показанная в листинге 22.11, вызывается после получения ответа для обновления оценочного значения RTT и вычисления нового значения RTO. Листинг 22.11. Функция rtt_stop: обновление показателей RTT и вычисление нового
//lib/rtt.c
62 void
63 rtt_stop(struct rtt_info *ptr, uint32_t ms)
64 {
65 double delta;
66 ptr->rtt_rtt = ms / 1000.0; /* измеренное значение RTT в секундах */
Поделиться:
Популярные книги
Возвышение Меркурия. Книга 17
17. Меркурий
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Мастер Разума
1. Мастер Разума
Фантастика:
героическая фантастика
попаданцы
аниме
6.20
рейтинг книги
Ты нас предал
1. Измены. Кантемировы
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Свои чужие
2. Не родные
Любовные романы:
современные любовные романы
6.71
рейтинг книги
Отверженный. Дилогия
Отверженный
Фантастика:
фэнтези
7.51
рейтинг книги
Прогрессор поневоле
2. Фараон
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Черный Маг Императора 8
8. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Его наследник
1. Наследники Сильных
Любовные романы:
современные любовные романы
эро литература
5.87
рейтинг книги
Мне нужна жена
Любовные романы:
современные любовные романы
6.88
рейтинг книги
Гримуар темного лорда VI
6. Гримуар темного лорда
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Кротовский, может, хватит?
3. РОС: Изнанка Империи
Фантастика:
попаданцы
альтернативная история
аниме
7.50
рейтинг книги
Темный Лекарь
1. Темный Лекарь
Фантастика:
фэнтези
аниме
5.00
рейтинг книги
Страж Кодекса. Книга IV
4. КО: Страж Кодекса
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Довлатов. Сонный лекарь 2
2. Не вывожу
Фантастика:
альтернативная история
аниме
5.00