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

на главную - закладки

Жанры

UNIX: разработка сетевых приложений
Шрифт:

67 /*

68 * Обновляем оценочные значения RTT среднего отклонения RTT.

69 * (См. статью Джекобсона (Jacobson). SIGCOMM'88. Приложение А.)

70 * Здесь мы для простоты используем числа с плавающей точкой.

71 */

72 delta = ptr->rtt_rtt - ptr->rtt_srtt;

73 ptr->rtt_srtt += delta / 8; /* g - 1/8 */

74 if (delta < 0.0)

75 delta = -delta; /* |delta| */

76 ptr->rtt_rttvar += (delta - ptr->rtt_rttvar) / 4; /* h - 1/4 */

77 ptr->rtt_rto = rtt_minmax(RTT_RTOCALC(ptr));

78 }

62-78
Вторым аргументом является измеренное RTT, полученное вызывающим процессом при вычитании полученной в ответе отметки времени из текущей (функция
rtt_ts
). Затем применяются уравнения, приведенные в начале этого раздела, и записываются новые значения переменных
rtt_srtt
,
rtt_rttvar
и
rtt_rto
.

Последняя функция,

rtt_timeout
показана в листинге 22.12. Эта функция вызывается, когда истекает время таймера повторных передач.

Листинг 22.12. Функция rtt_timeout: применение экспоненциального смещения

//lib/rtt.c

83 int

84 rtt_timeout(struct rtt_info *ptr)

85 {

86 ptr->rtt_rto *= 2; /* следующее значение RTO */

87 if (++ptr->rtt_nrexmt > RTT_MAXNREXMT)

88 return (-1); /* закончилось время, отпущенное на попытки отправить

этот пакет */

89 return (0);

90 }

86
Текущее значение RTO удваивается — в этом и заключается экспоненциальное смещение.

87-89
Если мы достигли максимально возможного количества повторных передач, возвращается значение -1, указывающее вызывающему процессу, что дальнейшие попытки передачи должны прекратиться. В противном случае возвращается 0.

В нашем примере клиент соединялся дважды с двумя различными эхо-серверами в Интернете утром рабочего дня. Каждому серверу было отправлено по 500 строк. По пути к первому серверу было потеряно 8 пакетов, по пути ко второму — 16. Один из потерянных шестнадцати пакетов, предназначенных второму серверу, был потерян дважды, то есть пакет пришлось дважды передавать повторно, прежде чем был получен ответ. Все остальные потерянные пакеты пришлось передать повторно только один раз. Мы могли убедиться, что эти пакеты были действительно потеряны, посмотрев на выведенные порядковые номера каждого из полученных пакетов. Если пакет лишь опоздал, но не был потерян, после повторной передачи клиент получает два ответа: соответствующий запоздавшему первому пакету и повторно переданному. Обратите внимание, что у нас нет возможности определить, что именно было потеряно (и привело к необходимости повторной

передачи клиентского запроса) — сам клиентский запрос или же ответ сервера, высланный после получения такого запроса.

ПРИМЕЧАНИЕ

Для первого издания этой книги автор написал для проверки этого клиента сервер UDP, который случайным образом игнорировал пакеты. Теперь он не используется. Нужно только соединить клиент с сервером через Интернет, и тогда нам почти гарантирована потеря некоторых пакетов!

22.6. Связывание с адресами интерфейсов

Одно из типичных применений функции

get_ifi_info
связано с приложениями UDP, которым нужно выполнять мониторинг всех интерфейсов на узле, чтобы знать, когда и на какой интерфейс приходит дейтаграмма. Это позволяет получающей программе узнавать адрес получателя дейтаграммы UDP, так как именно по этому адресу определяется сокет, на который доставляется дейтаграмма, даже если узел не поддерживает параметр сокета
IP_RECVDSTADDR
.

ПРИМЕЧАНИЕ

Вспомните наше обсуждение в конце раздела 22.2. Если узел использует более распространенную модель системы с гибкой привязкой (см. раздел 8.8), IP-адрес получателя может отличаться от IP-адреса принимающего интерфейса. В этом случае мы можем определить только адрес получателя дейтаграммы, который не обязательно должен быть адресом, присвоенным принимающему интерфейсу. Чтобы определить принимающий интерфейс, требуется параметр сокета IP_RECVIF или IPV6_PKTINFO.

В листинге 22.13 показана первая часть примера применения этой технологии к эхо-серверу UDP, который связывается со всеми адресами направленной передачи, широковещательной передачи и, наконец, с универсальными адресами.

Листинг 22.13. Первая часть сервера UDP, который с помощью функции bind связывается со всеми адресами

//advio/udpserv03.c

1 #include "unpifi.h"

2 void mydg_echo(int, SA*, socklen_t, SA*);

3 int

4 main(int argc, char **argv)

5 {

6 int sockfd;

7 const int on = 1;

8 pid_t pid;

9 struct ifi_info *ifi, *ifihead;

10 struct sockaddr_in *sa, cliaddr, wildaddr;

11 for (ifihead = ifi = Get_ifi_info(AF_INET, 1);

12 ifi != NULL; ifi = ifi->ifi_next) {

13 /* связываем направленный адрес */

14 sockfd = Socket(AF_INET, SOCK_DGRAM, 0);

15 Setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));

16 sa = (struct sockaddr_in*)ifi->ifi_addr;

17 sa->sin_family = AF_INET;

Поделиться:
Популярные книги

Возвышение Меркурия. Книга 17

Кронос Александр
17. Меркурий
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 17

Мастер Разума

Кронос Александр
1. Мастер Разума
Фантастика:
героическая фантастика
попаданцы
аниме
6.20
рейтинг книги
Мастер Разума

Ты нас предал

Безрукова Елена
1. Измены. Кантемировы
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Ты нас предал

Свои чужие

Джокер Ольга
2. Не родные
Любовные романы:
современные любовные романы
6.71
рейтинг книги
Свои чужие

Отверженный. Дилогия

Опсокополос Алексис
Отверженный
Фантастика:
фэнтези
7.51
рейтинг книги
Отверженный. Дилогия

Прогрессор поневоле

Распопов Дмитрий Викторович
2. Фараон
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Прогрессор поневоле

Черный Маг Императора 8

Герда Александр
8. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Черный Маг Императора 8

Его наследник

Безрукова Елена
1. Наследники Сильных
Любовные романы:
современные любовные романы
эро литература
5.87
рейтинг книги
Его наследник

Мне нужна жена

Юнина Наталья
Любовные романы:
современные любовные романы
6.88
рейтинг книги
Мне нужна жена

Гримуар темного лорда VI

Грехов Тимофей
6. Гримуар темного лорда
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Гримуар темного лорда VI

Кротовский, может, хватит?

Парсиев Дмитрий
3. РОС: Изнанка Империи
Фантастика:
попаданцы
альтернативная история
аниме
7.50
рейтинг книги
Кротовский, может, хватит?

Темный Лекарь

Токсик Саша
1. Темный Лекарь
Фантастика:
фэнтези
аниме
5.00
рейтинг книги
Темный Лекарь

Страж Кодекса. Книга IV

Романов Илья Николаевич
4. КО: Страж Кодекса
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Страж Кодекса. Книга IV

Довлатов. Сонный лекарь 2

Голд Джон
2. Не вывожу
Фантастика:
альтернативная история
аниме
5.00
рейтинг книги
Довлатов. Сонный лекарь 2