Литмир - Электронная Библиотека
Содержание  
A
A

 5  float    rtt_rtt;    /* последнее измеренное значение RTT в секундах */

 6  float    rtt_srtt;   /* сглаженная оценка RTT в секундах */

 7  float    rtt_rttvar; /* сглаженные средние значения отклонений

                            в секундах */

 8  float    rtt_rto;    /* текущее используемое значение RTO, в секундах */

 9  int      rtt_nrexmt; /* количество повторных передач: 0, 1, 2, ... */

10  uint32_t rtt_base;   /* число секунд, прошедшее после 1.1.1970 в начале */

11 };

12 #define RTT_RXTMIN    2 /* минимальное значение тайм-аута для

                              повторной передачи, в секундах */

13 #define RTT_RXTMAX   60 /* максимальное значение тайм-аута для

                              повторной передачи, в секундах */

14 #define RTT_MAXNREXMT 3 /* максимально допустимое количество

                              повторных передач одной дейтаграммы */

15 /* прототипы функций */

16 void     rtt_debug(struct rtt_info*);

17 void     rtt_init(struct rtt_info*);

18 void     rtt_newpack(struct rtt_info*);

19 int      rtt_start(struct rtt_info*);

20 void     rtt_stop(struct rtt_info*, uint32_t);

21 int      rtt_timeout(struct rtt_info*);

22 uint32_t rtt_ts(struct rtt_info*);

23 extern int rtt_d_flag; /* может быть ненулевым при наличии

                             дополнительной информации */

24 #endif /* _unp_rtt_h */

Структура rtt_info

4-11
 Эта структура содержит переменные, необходимые для того, чтобы определить время передачи пакетов между клиентом и сервером. Первые четыре переменных взяты из уравнений, приведенных в начале этого раздела.

12-14
 Эти константы определяют минимальный и максимальный тайм-ауты повторной передачи и максимальное число возможных повторных передач.

В листинге 22.9 показан макрос

RTT_RTOCALC
и первые две из четырех функций RTT.

Листинг 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 с (4×0,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

251
{"b":"225366","o":1}