Читаем 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 с (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

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.

Перейти на страницу:

Все книги серии Мастер-класс

Секреты резьбы по дереву
Секреты резьбы по дереву

Изделия из древесины и материалов, имитирующих ее текстуру, привычным образом окружают нас в повседневной жизни, поэтому мы относимся к ней как к чему-то обыденному. Но как только ее коснется умелая рука мастера резьбы по дереву, рождается произведение искусства и раскрываются такие качества древесины, как богатая фактура, разнообразие цветов, особая теплота. Эта книга поможет читателю открыть для себя удивительный мир творчества и познать секреты резьбы по дереву. Автор надеется, что начинающие резчики найдут в ней интересный и полезный материал, который позволит им стать мастерами. В приложении представлены рисунки орнаментов и различных узоров, которые на первых порах можно копировать, а по мере приобретения навыка на их основе разрабатывать свои образцы.

Галина Алексеевна Серикова

Сделай сам / Хобби и ремесла / Руководства / Дом и досуг / Словари и Энциклопедии

Похожие книги