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 в секундах */
Поделиться:
Популярные книги
Энфис 5
5. Эрра
Фантастика:
героическая фантастика
рпг
аниме
5.00
рейтинг книги
Последняя Арена 7
7. Последняя Арена
Фантастика:
рпг
постапокалипсис
5.00
рейтинг книги
Бандит 2
2. Петр Синельников
Фантастика:
боевая фантастика
5.73
рейтинг книги
Деспот
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
Энфис. Книга 1
1. Эрра
Фантастика:
боевая фантастика
рпг
5.70
рейтинг книги
Релокант
1. Релокант в другой мир
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Медиум
1. О чем молчат могилы
Фантастика:
фэнтези
7.90
рейтинг книги
Гром над Тверью
1. Гром над миром
Фантастика:
боевая фантастика
5.89
рейтинг книги
Служанка. Второй шанс для дракона
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Я – Стрела. Трилогия
Я - Стрела
Любовные романы:
любовно-фантастические романы
эро литература
6.82
рейтинг книги
На границе империй. Том 7. Часть 3
9. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.40
рейтинг книги
Хозяйка дома в «Гиблых Пределах»
Любовные романы:
любовно-фантастические романы
5.75
рейтинг книги
Сила рода. Том 1 и Том 2
1. Претендент
Фантастика:
фэнтези
рпг
попаданцы
5.85
рейтинг книги
Сильнейший ученик. Том 2
2. Пробуждение крови
Фантастика:
фэнтези
попаданцы
аниме
5.00