Чтение онлайн

на главную

Жанры

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
рейтинг книги
Энфис 5

Последняя Арена 7

Греков Сергей
7. Последняя Арена
Фантастика:
рпг
постапокалипсис
5.00
рейтинг книги
Последняя Арена 7

Бандит 2

Щепетнов Евгений Владимирович
2. Петр Синельников
Фантастика:
боевая фантастика
5.73
рейтинг книги
Бандит 2

Деспот

Шагаева Наталья
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
Деспот

Энфис. Книга 1

Кронос Александр
1. Эрра
Фантастика:
боевая фантастика
рпг
5.70
рейтинг книги
Энфис. Книга 1

Релокант

Ascold Flow
1. Релокант в другой мир
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Релокант

Медиум

Злобин Михаил
1. О чем молчат могилы
Фантастика:
фэнтези
7.90
рейтинг книги
Медиум

Гром над Тверью

Машуков Тимур
1. Гром над миром
Фантастика:
боевая фантастика
5.89
рейтинг книги
Гром над Тверью

Служанка. Второй шанс для дракона

Шёпот Светлана
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Служанка. Второй шанс для дракона

Я – Стрела. Трилогия

Суббота Светлана
Я - Стрела
Любовные романы:
любовно-фантастические романы
эро литература
6.82
рейтинг книги
Я – Стрела. Трилогия

На границе империй. Том 7. Часть 3

INDIGO
9. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.40
рейтинг книги
На границе империй. Том 7. Часть 3

Хозяйка дома в «Гиблых Пределах»

Нова Юлия
Любовные романы:
любовно-фантастические романы
5.75
рейтинг книги
Хозяйка дома в «Гиблых Пределах»

Сила рода. Том 1 и Том 2

Вяч Павел
1. Претендент
Фантастика:
фэнтези
рпг
попаданцы
5.85
рейтинг книги
Сила рода. Том 1 и Том 2

Сильнейший ученик. Том 2

Ткачев Андрей Юрьевич
2. Пробуждение крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Сильнейший ученик. Том 2