22.5. Добавление надежности приложению UDP

22.5. Добавление надежности приложению UDP

Если мы хотим использовать UDP для приложения типа «запрос-ответ», как было отмечено в предыдущем разделе, мы должны добавить нашему клиенту две функции:

? тайм-аут и повторную передачу, которые позволяют решать проблемы, возникающие в случае потери дейтаграмм;

? порядковые номера, позволяющие клиенту проверить, что ответ приходит на определенный запрос.

Эти два свойства предусмотрены в большинстве существующих приложений UDP, использующих простую модель «запрос-ответ»: например, распознаватели DNS, агенты SNMP, TFTP и RPC. Мы не пытаемся использовать UDP для передачи большого количества данных: наша цель — приложение, посылающее запрос и ожидающее ответа на этот запрос.

ПРИМЕЧАНИЕ

Использование дейтаграмм по определению не может быть надежным, следовательно, мы специально не называем данный сервис «надежным сервисом дейтаграмм». Действительно, термин «надежная дейтаграмма» — это оксюморон. Речь идет лишь о том, что приложение до некоторой степени обеспечивает надежность, добавляя соответствующие функциональные возможности «поверх» ненадежного сервиса дейтаграмм (UDP).

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

Более старый метод реализации тайм-аутов и повторной передачи заключался в отправке запроса и ожидании в течение N секунд. Если ответ не приходил, осуществлялась повторная передача и снова на ожидание ответа отводилось N секунд. Если это повторялось несколько раз, отправка запроса прекращалась. Это так называемый линейный таймер повторной передачи (на рис. 6.8 [111] показан пример клиента TFTP, использующего эту технологию. Многие клиенты TFTP до сих пор пользуются этим методом).

Проблема при использовании этой технологии состоит в том, что количество времени, в течение которого дейтаграмма совершает цикл в объединенной сети, может варьироваться от долей секунд в локальной сети до нескольких секунд в глобальной. Факторами, влияющими на время обращения (RTT), являются расстояние, скорость сети и переполнение. Кроме того, RTT между клиентом и сервером может быстро меняться со временем при изменении условий в сети. Нам придется использовать тайм-ауты и алгоритм повторной передачи, который учитывает действительное (измеряемое) значение периода RTT и изменения RTT с течением времени. В этой области ведется большая исследовательская работа, в основном направленная на TCP, но некоторые идеи применимы к любым сетевым приложениям.

Мы хотим вычислить тайм-аут повторной передачи (RTO), чтобы использовать его при отправке каждого пакета. Для того чтобы выполнить это вычисление, мы измеряем RTT — действительное время обращения для пакета. Каждый раз, измеряя RTT, мы обновляем два статистических показателя: srtt — сглаженную оценку RTT, и rttvar — сглаженную оценку среднего отклонения. Последняя является хорошей приближенной оценкой стандартного отклонения, но ее легче вычислять, поскольку для этого не требуется извлечения квадратного корня. Имея эти два показателя, мы вычисляем RTO как сумму srtt и rttvar, умноженного на четыре. В [52] даются все необходимые подробности этих вычислений, которые мы можем свести к четырем следующим уравнениям:

delta = measuredRTT - srtt

srtt ? srtt + g ? delta

rttvar ? rttvar + h (|delta| - rttvar)

RTO = srtt + 4 ? rttvar

delta — это разность между измеренным RTT и текущим сглаженным показателем RTT (srtt). g — это приращение, применяемое к показателю RTT, равное 1/8. h — это приращение, применяемое к сглаженному показателю среднего отклонения, равное ?.

ПРИМЕЧАНИЕ

Два приращения и множитель 4 в вычислении RTO специально выражены степенями числа 2 и могут быть вычислены с использованием операций сдвига вместо деления и умножения. На самом деле реализация TCP в ядре (см. раздел 25.7 [128]) для ускорения вычислений обычно использует арифметику с фиксированной точкой, но мы для простоты используем в нашем коде вычисления с плавающей точкой.

Другой важный момент, отмеченный в [52], заключается в том, что по истечении времени таймера повторной передачи для следующего RTO должно использоваться экспоненциальное смещение (exponential backoff). Например, если наше первое значение RTO равно 2 с и за это время ответа не получено, следующее значение RTO будет равно 4 с. Если ответ все еще не последовал, следующее значение RTO будет 8 с, затем 16 и т.д.

Алгоритмы Джекобсона (Jacobson) реализуют вычисление RTO при измерении RTT и увеличение RTO при повторной передаче. Однако, когда клиент выполняет повторную передачу и получает ответ, возникает проблема неопределенности повторной передачи (retransmission ambiguity problem). На рис. 22.2 показаны три возможных сценария, при которых истекает время ожидания повторной передачи:

? запрос потерян;

? ответ потерян;

? значение RTO слишком мало.

Рис. 22.2. Три сценария, возможные при истечении времени таймера повторной передачи

Когда клиент получает ответ на запрос, отправленный повторно, он не может сказать, какому из запросов соответствует ответ. На рисунке, изображенном справа, ответ соответствует начальному запросу, в то время как на двух других рисунках ответ соответствуют второму запросу.

Алгоритм Карна (Karn) [58] обрабатывает этот сценарий в соответствии со следующими правилами, применяемыми в любом случае, когда ответ получен на запрос, отправленный более одного раза:

? Если для запроса и ответа было измерено значение RTT, не следует использовать его для обновления оценочных значений, так как мы не знаем, какому запросу соответствует ответ.

? Поскольку ответ пришел до того, как истекло время нашего таймера повторной передачи, используйте для следующего пакета текущее значение RTO. Только когда мы получим ответ на запрос, который не был передан повторно, мы изменяем значение RTT и снова вычисляем RTO.

При написании наших функций RTT применить алгоритм Карна несложно, но оказывается, что существует и более изящное решение. Оно используется в расширениях TCP для сетей с высокой пропускной способностью, то есть сетей, обладающих либо широкой полосой пропускания, либо большим значением RTT, либо обоими этими свойствами (RFC 1323 [53]). Кроме добавления порядкового номера к началу каждого запроса, который сервер должен отразить, мы добавляем отметку времени, которую сервер также должен отразить. Каждый раз, отправляя запрос, мы сохраняем в этой отметке значение текущего времени. Когда приходит ответ, мы вычисляем величину RTT для этого пакета как текущее время минус значение отметки времени, отраженной сервером в своем ответе. Поскольку каждый запрос несет отметку времени, отражаемую сервером, мы можем вычислить RTT для каждого ответа, который мы получаем. Теперь нет никакой неопределенности. Более того, поскольку сервер только отражает отметку времени клиента, клиент может использовать для отметок времени любые удобные единицы, и при этом не требуется, чтобы клиент и сервер синхронизировали часы.

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

3.1.4 Формулировки надежности

Из книги Пакеты программ. Требования к качеству и тестирование автора Автор неизвестен

3.1.4 Формулировки надежности В описание продукта должна быть включена информация по процедурам сохранения данных.Примечание - Данную информацию можно привести, указав, например, возможности резервирования данных с помощью функций операционной системы.Могут быть


Добавление

Из книги Pinnacle Studio 11 автора Чиртик Александр Анатольевич

Добавление Добавление в титр статических изображений и кнопок производится с помощью специальных вкладок редактора титров, и потому рассмотрено отдельно. Сейчас же мы узнаем, как добавить в титр надписи, прямоугольники и эллипсы. Описанные далее операции (выделение,


2.2.7 Средства обеспечения надежности

Из книги Руководство администратора баз данных Informix. автора Кустов Виктор

2.2.7 Средства обеспечения надежности Сервер INFORMIX-OnLine DS предоставляет следующие средства для восстановления после сбоев и обеспечения отказоустойчивости: Зеркалирование дисковых областейПолное тиражирование данных сервераБыстрое восстановление при включении


Проблема надежности

Из книги Основы объектно-ориентированного программирования автора Мейер Бертран

Проблема надежности Допустим, разработчик управляет утилизацией объектов с помощью механизма reclaim. Возможность ошибочного вызова reclaim всегда существует; особенно при наличии сложных структур данных. В жизненном цикле ПО reclaim, бывшее когда-то правильным, может стать


Базисные механизмы надежности

Из книги TCP/IP Архитектура, протоколы, реализация (включая IP версии 6 и IP Security) автора Фейт Сидни М

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


Интуиция (Дзен) и искусство программной надежности: больше гарантий и меньше проверок

Из книги Интернет на 100%. Подробный самоучитель: от «чайника» – до профессионала автора Гладкий Алексей Анатольевич

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


10.3 Механизм обеспечения надежности TCP

Из книги Программирование на языке Пролог для искусственного интеллекта автора Братко Иван

10.3 Механизм обеспечения надежности TCP В этом разделе мы рассмотрим механизм TCP, используемый для надежной доставки данных при сохранении порядка пересылки и исключения потерь либо


Как разрешить приложению работать через брандмауэр Windows

Из книги Программирование КПК и смартфонов на .NET Compact Framework автора Климов Александр П.

Как разрешить приложению работать через брандмауэр Windows Брандмауэр Windows 7 по умолчанию блокирует работу большинства установленных на компьютере приложений. Собственно, во многом благодаря именно этому и достигается высокий уровень безопасности компьютера: если


3.2.3. Добавление элемента

Из книги Delphi. Трюки и эффекты автора Чиртик Александр Анатольевич

3.2.3. Добавление элемента Наиболее простой способ добавить элемент в список — это вставить его в самое начало так, чтобы он стал его новой головой. Если X — это новый элемент, а список, в который X добавляется — L, тогда результирующий список — это просто[X | L]Таким


5.2.3. Добавление элемента к списку, если он в нем отсутствует (добавление без дублирования)

Из книги Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ автора Борри Хелен

5.2.3. Добавление элемента к списку, если он в нем отсутствует (добавление без дублирования) Часто требуется добавлять элемент X в список L только в том случае, когда в списке еще нет такого элемента. Если же X уже есть в L, тогда L необходимо оставить без изменения, поскольку


Путь к запущенному приложению

Из книги Как сделать свой сайт и заработать на нем. Практическое пособие для начинающих по заработку в Интернете автора Мухутдинов Евгений

Путь к запущенному приложению Иногда требуется узнать путь к файлу запущенного приложения. Для этого можно воспользоваться кодом из листинга 14.3.Листинг 14.3using System.IO;using System.Reflection;txtAppDir.Text = Path.GetDirectoryName(Assembly.GetExecutingAssemblу().GetModule()[0].  FullyQuelifiedName).ToString();В этом примере после выбора


1.1. Привлечение внимания к приложению

Из книги Использование NuMega DriverStudio для написания WDM-драйверов автора Тарво Александр

1.1. Привлечение внимания к приложению Начнем с простых примеров, позволяющих привлечь внимание пользователя к определенному окну приложения. Это может пригодиться в различных ситуациях: от уведомления пользователя об ошибке программы до простой сигнализации ему, какое


Добавление

Из книги QT 4: программирование GUI на С++ автора Бланшет Жасмин

Добавление Не существует "дельт" или блокировок для добавления. Если другая транзакция перед этим не выполняла добавления в условиях блокировки на уровне таблицы, добавление всегда будет успешным, если оно не нарушает каких-либо ограничений или проверок


Написание подключаемых к приложению модулей

Из книги автора

Написание подключаемых к приложению модулей Подключаемый к приложению модуль является подклассом QObject и интерфейсов, которые он собирается обеспечить. Прилагаемый к этой книге компакт-диск содержит два подключаемых модуля, предназначенных для приложения Text Art,