Какой тип приложений лучше всего подходит для использования протокола udp
— это простой, ориентированный на дейтаграммы протокол без организации соединения, предоставляющий быстрое, но необязательно надежное транспортное обслуживание. Он поддерживает взаимодействия "один со многими" и поэтому часто применяется для широковещательной и групповой передачи дейтаграмм.
Internet Protocol (IP) является основным протоколом Интернета. Transmission Control Protocol (TCP) и UDP — это протоколы транспортного уровня, построенные поверх лежащего в основе протокола.
TCP/IP — это набор протоколов, называемый также "пакетом протоколов Интернета" (Internet Protocol Suite), состоящий из четырех уровней. Запомните, что TCP/IP не просто один протокол, а семейство или набор протоколов, который состоит из других низкоуровневых протоколов, таких, как IP, TCP и UDP. UDP располагается на транспортном уровне поверх IP (протокола сетевого уровня). Транспортный уровень обеспечивает взаимодействие между сетями через шлюзы. В нем используются IP-адреса для отправки пакетов данных через Интернет или другую сеть с помощью разнообразных драйверов устройств.
Прежде чем приступать к изучению работы UDP, обратимся к основной терминологии, которую нужно хорошо знать. Ниже вкратце определим основные термины, связанные с UDP:
Пакеты
В передаче данных пакетом называется последовательность двоичных цифр, представляющих данные и управляющие сигналы, которые передаются и коммутируются через хост. Внутри пакета эта информация расположена в соответствии со специальным форматом.
Дейтаграммы
Дейтаграмма — это отдельный, независимый пакет данных, несущий информацию, достаточную для передачи от источника до пункта назначения, поэтому никакого дополнительного обмена между источником, адресатом и транспортной сетью не требуется.
MTU (Maximum Transmission Unit)
MTU характеризует канальный уровень и соответствует максимальному числу байтов, которое можно передать в одном пакете. Другими словами MTU — это самый большой пакет, который может переносить данная сетевая среда. Например, Ethernet имеет фиксированный MTU, равный 1500 байтам. В UDP, если размер дейтаграммы больше MTU, протокол IP выполняет фрагментацию, разбивая дейтаграмму на более мелкие части (фрагменты) так, чтобы каждый фрагмент был меньше MTU.
Порты
Чтобы поставить в соответствие входящим данным конкретный процесс, выполняемый в компьютере, UDP использует порты. UDP направляет пакет в соответствующее место, используя номер порта, указанный в UDP-заголовке дейтаграммы. Порты представлены 16-битными номерами и, следовательно, принимает значения в диапазоне от 0 до 65 535. Порты, которые также называют конечными точками логических соединений, разделены на три категории:
Хорошо известные порты - от 0 до 1023
Регистрируемые порты — от 1024 до 49151
Динамические / частные порты — от 49152 до 65535
UDP использует следующие известные порты:
Номер порта | Описание |
---|---|
15 | NETSTAT — Состояние сети |
53 | DNS — Сервер доменных имен |
69 | TFTP - Простейший протокол передачи файлов |
137 | Служба имен NetBIOS |
138 | Дейтаграммная служба NetBIOS |
161 | SMTP |
Перечень портов UDP и TCP поддерживается агентством IANA (Internet Assigned Numbers Authority).
IP-адреса
Однонаправленный IP-адрес уникально определяет хост в сети, тогда как групповой IP-адрес определяет конкретную группу адресов в сети. Широковещательные IP-адреса получаются и обрабатываются всеми хостами локальной сети или конкретной подсети.
TTL
Значение времени жизни, или TTL (time-to-live), позволяет установить верхний предел числа маршрутизаторов, через которые может пройти дейтаграмма. Значение TTL не дает пакетам попасть в бесконечные циклы. Оно инициализируется отправителем и уменьшается на единицу каждым маршрутизатором, обрабатывающим дейтаграмму. Когда значение TTL становится нулевым, дейтаграмма отбрасывается.
Групповая рассылка
Групповая рассылка — это открытый, базирующийся на стандартах, метод одновременного распространения идентичной информации нескольким пользователям. Групповая рассылка является основным средством протокола UDP, она невозможна для протокола TCP. Групповая рассылка позволяет добиться взаимодействия одного со многими, например, делает возможными такие использования, как рассылка новостей и почты нескольким получателям, интернет-радио или демонстрационные программы реального времени. Групповая рассылка не так сильно нагружает сеть, как широковещательная передача, поскольку данные отправляются сразу нескольким пользователям:
Принцип работы UDP
Когда приложение, базирующееся на UDP, отправляет данные другому хосту в сети, UDP дополняет их восьмибитным заголовком, содержащим номера портов адресата и отправителя, общую длину данных и контрольную сумму. Поверх дейтаграммы UDP свой заголовок добавляет IP, формируя дейтаграмму IP:
На предыдущем рисунке указано, что общая длина заголовка UDP составляет восемь байтов. Теоретически максимальный размер дейтаграммы IP равен 65 535 байтам. С учетом 20 байтов заголовка IP и 8 байтов заголовка UDP длина данных пользователя может достигать 65 507 байтов. Однако большинство программ работают с данными меньшего размера. Так, для большинства приложений по умолчанию установлена длина приблизительно 8192 байта, поскольку именно такой объем данных считывается и записывается сетевой файловой системой (NFS). Можно устанавливать размеры входного и выходного буферов.
Контрольная сумма нужна, чтобы проверить были ли данные доставлены в пункт назначения правильно или были искажены. Она охватывает как заголовок UDP, так и данные. Байт-заполнитель используется, если общее число октетов дейтаграммы нечетно. Если полученная контрольная сумма равна нулю, получатель фиксирует ошибку контрольной суммы и отбрасывает дейтаграмму. Хотя контрольная сумма является необязательным средством, ее всегда рекомендуется включать.
На следующем шаге уровень IP добавляет 20 байтов заголовка, включающего TTL, IP-адреса источника и получателя и другую информацию. Это действие называют IP-инкапсуляцией.
Как упоминалось ранее, максимальный размер пакета равен 65 507 байтам. Если пакет превышает установленный по умолчанию размер MTU, то уровень IP разбивает пакет на сегменты. Эти сегменты называются фрагментами, а процесс разбиения данных на сегменты — фрагментацией. Заголовок IP содержит всю информацию о фрагментах.
Когда приложение-отправитель "выбрасывает" дейтаграмму в сеть, она направляется по IP-адресу назначения, указанному в заголовке IP. При проходе через маршрутизатор значение времени жизни (TTL) в заголовке IP уменьшается на единицу.
Когда дейтаграмма прибывает к заданному назначению и порту, уровень IP по своему заголовку проверяет, фрагментирована ли дейтаграмма. Если это так, дейтаграмма собирается в соответствии с информацией, имеющейся в заголовке. Наконец прикладной уровень извлекает отфильтрованные данные, удаляя заголовок.
Недостатки UDP
По сравнению с TCP UDP имеет следующие недостатки:
Отсутствие сигналов квитирования. Перед отправкой пакета UDP, отправляющая сторона не обменивается с получающей стороной квитирующими сигналами. Следовательно, у отправителя нет способа узнать, достигла ли дейтаграмма конечной системы. В результате UDP не может гарантировать, что данные будут действительно доставлены адресату (например, если не работает конечная система или сеть).
Напротив, протокол TCP ориентирован на установление соединений и обеспечивает взаимодействие между подключенными к сети хостами, используя пакеты. В TCP применяются сигналы квитирования, позволяющие проверить успешность транспортировки данных.
Использование сессий. Ориентированность TCP на соединения поддерживается сеансами между хостами. TCP использует идентификатор сеанса, позволяющий отслеживать соединения между двумя хостами. UDP не имеет поддержки сеансов из-за своей природы, не ориентированной на соединения.
Безопасность. TCP более защищен, чем UDP. Во многих организациях брандмауэры и маршрутизаторы не пропускают пакеты UDP. Это связано с тем, что хакеры могут воспользоваться портами UDP, не устанавливая явных соединений.
Управление потоком. В UDP управление потоком отсутствует, в результате плохо спроектированное UDP-приложение может захватить значительную часть пропускной способности сети.
Преимущества UDP
По сравнению с TCP UDP имеет следующие преимущества:
Нет установки соединения. UDP является протоколом без организации соединений, поэтому он освобождает от накладных расходов, связанных с установкой соединений. Поскольку UDP не пользуется сигналами квитирования, то задержек, вызванных установкой соединений, также удается избежать. Именно поэтому DNS отдает предпочтение UDP перед TCP — DNS работала бы гораздо медленнее, если бы она выполнялась через TCP.
Скорость. UDP работает быстрее TCP. По этой причине многие приложения предпочитают не TCP, a UDP. Те же средства, которые делают TCP более устойчивым (например сигналы квитирования), замедляют его работу.
Топологическое разнообразие. UDP поддерживает взаимодействия "один с одним" и "один с многими", в то время как TCP поддерживает лишь взаимодействие "один с одним".
Накладные расходы. Работа с TCP означает повышенные накладные расходы, издержки, налагаемые UDP, существенно ниже. TCP по сравнению с UDP использует значительно больше ресурсов операционной системы, и, как следствие, в таких средах, где серверы одновременно обслуживают многих клиентов, широко используют UDP.
Размер заголовка. Для каждого пакета заголовок UDP имеет длину всего лишь восемь байтов, в то время как TCP имеет 20-байтовые заголовки, и поэтому UDP потребляет меньше пропускной способности сети.
Протокол User Datagram Protocol (UDP) использует Интернет-протокол для получения блока данных, который также называется датаграммой, с одного устройства на другое по сети. UDP - это облегченный протокол, определенный в Запросе Комментариев 768 в 1980 году. Она определяется как легковесная, так как не требует большой нагрузки, связанной с наличием деталей на заголовке. Реклама услуг, таких как обновление протоколов маршрутизации, доступность серверов и потоковых приложений, таких как видео и голос, является одним из основных видов использования UDP. [1]
Для UDP используется простая модель передачи данных. Это означает, что не существует гарантии целостности или надежности данных, обеспечивающей незащищенность, неупорядоченность, а иногда и дублирование датаграмм. В отличие от TCP, UDP не сильно полагается на исправление и проверку ошибок при выполнении. Таким образом, UDP хорошо подходит для мультикастинга или отправки всем абонентам, пакетного вещания или отправки всем абонентам в локальной сети. [2] UDP трафик, в отличие от TCP, не обязательно требует ответа и не обязательно устанавливать соединение для отправки. [3]
Cодержание
Функциональность
UDP, в отличие от TCP, посылает пакеты получателю независимо от того, могут ли они получить их полностью или нет. Каждый из пакетов отправляется отправителем получателю напрямую и индивидуально, без установления и подтверждения наличия надежного канала передачи данных. Пользователям не предоставляется возможность запрашивать недостающие пакеты данных после того, как они потеряны при транспортировке. [4] Данный тип протокола используется в основном в тех случаях, когда скорость передачи данных имеет более высокий приоритет, чем надежность успешной передачи данных. Нет внутреннего порядка передачи пакетов данных, и все пакеты передаются по сети независимо друг от друга.
Видео в прямом эфире
Например, пользователи, которые смотрят прямой видеопоток в интернете, полагаются на сервер, который посылает непрерывный поток пакетов данных. Большинство потоков видео в прямом эфире используют UDP, а не TCP. Когда зритель сталкивается с блокировкой экрана или задержкой во время трансляции, это вызвано потерей или обрывом соединения в виде потери пакетов во время передачи данных. Потеря пакетов, хотя и приводит к искажению видео или звука, но при передаче через UDP все равно позволяет воспроизводить видео целиком.
Онлайн игры
Аналогично, онлайн игры реализуют аналогичную концепцию. Символы проигрывателя могут появляться при телепортации по картам, когда вы получаете новые UDP-пакеты при пропуске некоторых из предыдущих передач данных. Игра продолжается, и пользователям не нужно извлекать старые и потерянные пакеты. Отмена коррекции ошибок TCP снижает задержки и улучшает скорость игрового соединения. [5] Отсутствие UDP пакетов во время игры приведет к незначительным сбоям, но не обязательно изменит ее производительность. В то время как игра продолжается в UDP, TCP зависимые игры будут иметь другой результат, который является целым замораживанием игры. В онлайн-играх важно то, что происходит в режиме реального времени. [6]
Эффекты
Как уникальный протокол, протокол User Datagram Protocol имеет свои плюсы и минусы. Некоторые из наиболее распространенных, с которыми вы столкнетесь, объясняются ниже.
Преимущества
Он имеет относительно более высокую скорость передачи данных благодаря небольшому весу пакетов с минимальными заголовками. Так как он не требует ответа, он подходит для видеоконференций, трансляций и игр.
Недостатки
Поскольку последовательность и подтверждение во время передачи данных отсутствуют, UDP считается ненадежной и небезопасной. Поврежденные пакеты удаляются, но не запрашиваются для повторной передачи, после того как они утеряны.
Протоколы и порты
Каждому устройству или компьютеру в Интернете присвоен свой уникальный номер, известный как IP-адрес. Это для конкретного компьютера, который должен быть идентифицирован, когда вы находитесь в Интернете. Информация, передаваемая через Интернет с компьютера, теперь принимается с помощью портов. Как и TCP, UDP также имеет свои специфические функции и порты. Ниже приведены некоторые из наиболее часто используемых для UDP.
Система доменных имен (DNS RFC 1034-1035: порт 53)
Протокол DNS является одним из широко используемых протоколов как в публичных, так и в частных сетях. Его основной целью является преобразование доменных имен в IP-адреса для маршрутизации по сети. широко используется в публичном интернете и частных сетях для преобразования доменных имен в IP-адреса, обычно для маршрутизации сети. DNS-серверы могут быть настроены внутри частной сети, не будучи частью глобальной системы.
Протокол динамической конфигурации хоста (DHCP RFC 2131: порт 67/68)
Этот протокол в основном используется в сетях, не использующих статические назначения IP-адресов. Сервер может быть настроен либо инженером, либо администратором, у которого есть доступный для назначения пул адресов. Клиент может включить устройство и запросить IP-адрес с локального DHCP-сервера, когда есть доступный адрес, он будет назначен устройству. Однако это не является постоянным назначением и истекает через определенный промежуток времени. Срок действия договора аренды истекает, если не подается запрос на продление, и он будет возвращен в пул для передачи другим устройствам.
Тривиальный протокол передачи файлов (TFP RFC 1350: порт 69)
Этот протокол, в отличие от обычного протокола передачи файлов, используемого в TCP, предлагает метод передачи данных без создания сеанса. Использование протокола TFTP не гарантирует, что передача файлов была выполнена должным образом. Этот протокол в основном используется для обновления микропрограммного обеспечения и программного обеспечения устройств.
Простой протокол сетевого управления (SNMP RFC 1901-1908, 3411-3418: порт 161-/162)
Этот протокол используется для управления сетью. Возможность мониторинга, настройки и управления сетевыми устройствами - это некоторые из возможностей SNMP. Ловушки также настраиваются таким образом, чтобы уведомлять о необходимости принятия конкретных мер и осуществлять дальнейший поиск источника события.
Протокол сетевого времени (NTP RFC 5905: порт 123)
Основной целью NTP является синхронизация устройств в Интернете, и считается одним из наиболее игнорируемых протоколов. Для поддержания точных часов в большинстве современных операционных систем используется протокол NTP. Устройство позволяет без особых усилий устранять неполадки на разных устройствах, поскольку часы точны, что делает NTP жизненно важной частью сетевых систем. [7]
В заключение хочу сказать, что на сегодняшний день UDP выполняет свою собственную задачу вместе с различными интернет-протоколами. Он все еще используется во многих основных приложениях, которые мы используем каждый день, например, для потоковой передачи видео и видеоконференций.
Такая архитектура Интернета достаточно правильна для клиент-серверного взаимодействия, когда клиенты могут находиться в частных сетях, а серверы имею глобальный адрес. Но она создает трудности для прямого соединения двух узлов между различными частными сетями. Прямое соединение двух узлов важно для «peer-to-peer» приложений, таких как передача голоса (Skype), получение удаленного доступа к компьютеру (TeamViewer), или онлайн игры.
Один из наиболее эффективных методов для установления peer-to-peer соединения между устройствами находящимися в различных частных сетях называется «hole punching». Этот техника чаще всего используется с приложениями на основе UDP протокола.
Но если вашему приложению требуется гарантированная доставка данных, например, вы передаете файлы между компьютерами, то при использовании UDP появится множество трудностей, связанных с тем, что UDP не является протоколом гарантированной доставки и не обеспечивает доставку пакетов по порядку, в отличие от TCP протокола.
В таком случае, для обеспечения гарантированной доставки пакетов, требуется реализовать протокол прикладного уровня, обеспечивающий необходимую функциональность и работающий поверх UDP.
Сразу хочу заметить, что существует техника TCP hole punching, для установления TCP соединений между узлами в разных частных сетях, но ввиду отсутствия поддержки её многими NAT устройствами она обычно не рассматривается как основной способ соединения таких узлов.
Далее в этой статье я буду рассматривать только реализацию протокола гарантированной доставки. Реализация техники UDP hole punching будет описана в следующих статьях.
Требования к протоколу
Для понимания данных требований, давайте рассмотрим временные диаграммы передачи данных между двумя узлами сети по протоколам TCP и UDP. Пусть в обоих случаях у нас будет потерян один пакет.
Как видно из диаграммы, в случае потери пакетов, TCP обнаружит потерянный пакет и сообщит об этом отправителю, запросив номер потерянного сегмента.
UDP не предпринимает никаких шагов по обнаружению потерь. Контроль ошибок передачи в UDP протоколе полностью возлагается на приложение.
Обнаружение ошибок в TCP протоколе достигается благодаря установке соединения с конечным узлом, сохранению состояния этого соединения, указанию номера отправленных байт в каждом заголовке пакета, и уведомлениях о получениях с помощью номера подтверждения «acknowledge number».
Дополнительно, для повышения производительности (т.е. отправки более одного сегмента без получения подтверждения) TCP протокол использует так называемое окно передачи — число байт данных которые отправитель сегмента ожидает принять.
Более подробно с TCP протоколом можно ознакомиться в rfc 793, с UDP в rfc 768, где они, собственно говоря, и определены.
Заголовок Reliable UDP
Вспомним, что UDP дейтаграмма инкапсулируется в IP дейтаграмму. Пакет Reliable UDP соответственно «заворачивается» в UDP дейтаграмму.
Структура заголовка Reliable UDP достаточно простая:
Общие принципы работы протокола
Диаграмма установление и завершение соединения:
Сторона-получатель принимает пакеты. Каждый пакет проверяется на попадание в окно передачи. Не попадающие в окно пакеты и дубликаты отсеиваются. Т.к. размер окна сторого фиксирован и одинаков у получателя и у отправителя, то в случае доставки блока пакетов без потерь, окно сдвигается для приема пакетов следующего блока данных и отправляется подтверждение о доставке. Если окно не заполнится за установленный рабочим таймером период, то будет запущена проверка на то, какие пакеты не были доставлены и будут отправлены запросы на повторную доставку.
Тайм-ауты и таймеры протокола
Существует несколько причин, по которым не может быть установлено соединение. Например, если принимающая сторона вне сети. В таком случае, при попытке установить соединение, соединение будет закрыто по тайм-ауту. В реализации Reliable UDP используются два таймера для установки тайм-аутов. Первый, рабочий таймер, служит для ожидания ответа от удаленного хоста. Если он срабатывает на стороне-отправителе, то выполняется повторная отправка последнего отправленного пакета. Если же таймер срабатывает у получателя, то выполняется проверка на потерянные пакеты и отправляются запросы на повторную доставку.
Второй таймер – необходим для закрытия соединения в случае отсутствия связи между узлами. Для стороны-отправителя он запускается сразу после срабатывания рабочего таймера, и ожидает ответа от удаленного узла. В случае отсутствия ответа за установленный период – соединение завершается и ресурсы освобождаются. Для стороны-получателя, таймер закрытия соединения запускается после двойного срабатывания рабочего таймера. Это необходимо для страховки от потери пакета подтверждения. При срабатывании таймера, также завершается соединение и высвобождаются ресурсы.
Диаграмма состояний передачи Reliable UDP
Принципы работы протокола реализованы в конечном автомате, каждое состояние которого отвечает за определенную логику обработки пакетов.
Диаграмма состояний Reliable UDP:
Closed – в действительности не является состоянием, это стартовая и конечная точка для автомата. За состояние Closed принимается блок управления передачей, который, реализуя асинхронный UDP сервер, перенаправляет пакеты в соответствующие соединения и запускает обработку состояний.
В нем проверяется корректность начала передачи, создаются необходимые структуры, и отправляется подтверждение о приеме первого пакета.
Глубже в код. Блок управления передачей
Один из ключевых элементов Reliable UDP – блок управления передачей. Задача данного блока – хранение текущих соединений и вспомогательных элементов, распределение пришедших пакетов по соответствующим соединениям, предоставление интерфейса для отправки пакетов соединению и реализация API протокола. Блок управления передачей принимает пакеты от UDP уровня и перенаправляет их на обработку в конечный автомат. Для приема пакетов в нем реализован асинхронный UDP сервер.
Некоторые члены класса ReliableUdpConnectionControlBlock: Некоторые члены класса ReliableUdpConnectionRecord:
Глубже в код. Состояния
Состояния реализуют конечный автомат протокола Reliable UDP, в котором происходит основная обработка пакетов. Абстрактный класс ReliableUdpState предоставляет интерфейс для состояния:
Всю логику работы протокола реализуют представленные выше классы, совместно со вспомогательным классом, предоставляющим статические методы, такие как, например, построения заголовка ReliableUdp из connection record.
Далее будут рассмотрены в подробностях реализации методов интерфейса, определяющих основные алгоритмы работы протокола.
Метод DisposeByTimeout
Он переопределен только в состоянии Completed.
Метод ProcessPackets
Метод ProcessPackets отвечает за дополнительную обработку пакета или пакетов. Вызывается напрямую, либо через таймер ожидания пакетов.
В состоянии Assembling метод переопределен и отвечает за проверку потерянных пакетов и переход в состояние Completed, в случае получения последнего пакета и прохождения успешной проверки
Метод ReceivePacket
В состоянии SendingCycle этот метод переопределен для приема подтверждений о доставке и запросов повторной передачи.
Метод SendPacket
В состоянии SendingCycle в этом методе происходит отправка блока пакетов.
Глубже в код. Создание и установление соединений
Теперь, когда мы познакомились с основными состояниями и методами, используемыми для обработки состояний, можно разобрать немного подробнее несколько примеров работы протокола.
Диаграмма передачи данных в нормальных условиях:
После отправки первого пакета отправитель переходит в состояние SendingCycle – ожидать подтверждения о доставке пакета.
Сторона-получатель, с помощью метода EndReceive, принимает отправленный пакет, создает новую connection record и передает данный пакет, с предварительно распарсенным заголовком, в обработку методу ReceivePacket состояния FirstPacketReceived
Прием первого пакета и отправка подтверждения (состояние FirstPacketReceived):
Глубже в код. Закрытие соединения по тайм-ауту
Отработка тайм-аутов важная часть Reliable UDP. Рассмотрим пример, в котором на промежуточным узле произошел сбой и доставка данных в обоих направления стала невозможной.
Как видно из диаграммы, рабочий таймер у отправителя включается сразу после отправки блока пакетов. Это происходит в методе SendPacket состояния SendingCycle.
Включение рабочего таймера (состояние SendingCycle):
Периоды таймера задаются при создании соединения. По умолчанию ShortTimerPeriod равен 5 секундам. В примере он установлен в 1,5 секунды.
У входящего соединения таймер запускается после получения последнего дошедшего пакета данных, это происходит в методе ReceivePacket состояния Assembling
Во входящем соединении за время ожидания рабочего таймера не пришло больше пакетов. Таймер сработал и вызывал метод ProcessPackets, в котором были обнаружены потерянные пакеты и первый раз отправлены запросы на повторную доставку.
Отправка запросов на повторную доставку (состояние Assembling):
Переменная TimerSecondTry установилась в true. Данная переменная отвечает за повторный перезапуск рабочего таймер.
Со стороны отправителя тоже срабатывает рабочий таймер и повторно отсылается последний отправленный пакет.
После чего в исходящем соединении запускается таймер закрытия соединения.
Период ожидания таймера закрытия соединения равен 30 секундам по-умолчанию.
Через непродолжительное время, повторно срабатывает рабочий таймер на стороне получателя, вновь производится отправка запросов, после чего запускается таймер закрытия соединения у входящего соединения
По срабатыванию таймеров закрытия все ресурсы обоих connection record освобождаются. Отправитель сообщает о неудачной доставке вышестоящему приложению (см. API Reliable UDP).
Глубже в код. Восстановление передачи данных
Диаграмма восстановления передачи данных при потере пакета:
Как уже обсуждалось в закрытии соединения по тайм-ауту, по истечению рабочего таймера у получателя произойдет проверка на потерянные пакеты. В случае наличия потерь пакетов будет составлен список номер пакетов, не дошедших до получателя. Данные номера заносятся в массив LostPackets конкретного соединения и выполняется отправка запросов на повторную доставку.
Отправка запросов на повторную доставку пакетов (состояние Assembling):
Отправитель примет запрос на повторную доставку и вышлет недостающие пакеты. Стоит заметить, что в этот момент у отправителя уже запущен таймер закрытия соединения и, при получении запроса, он сбрасывается.
Повторная отправка потерянных пакетов (состояние SendingCycle): Проверка на попадание в окно приема (состояние Assembling):
API Reliable UDP
Для взаимодействия с протоколом передачи данных имеется открытый класс Reliable Udp, являющийся оберткой над блоком управления передачей. Вот наиболее важные члены класса:
Заключение
Спасибо за внимание, жду Ваших комментариев и замечаний.
P.S. Для тех, кто интересуется подробностями или просто хочет протестировать протокол, ссылка на проект на GitHube:
Проект Reliable UDP
Полезные ссылки и статьи
Update: Спасибо mayorovp и sidristij за идею добавления task'а к интерфейсу. Совместимость библиотеки со старыми ОС не нарушается, т.к. 4-ый фреймворк поддерживает и XP и 2003 server.
Хотите улучшить этот вопрос? Обновите вопрос, чтобы он соответствовал теме переполнения стека.
Закрыто 3 года назад .
Так как TCP гарантирует доставку пакетов и поэтому может считаться «надежным», тогда как UDP ничего не гарантирует, и пакеты могут быть потеряны. В чем преимущество передачи данных с использованием UDP в приложении, а не через поток TCP? В каких ситуациях UDP будет лучшим выбором и почему?
Я предполагаю, что UDP работает быстрее, поскольку у него нет накладных расходов на создание и поддержание потока, но разве это не имеет значения, если некоторые данные никогда не достигают места назначения?
Помимо того, что UDP страдает от возможной потери пакетов, он не гарантирует, что вы получите пакет только один раз. Если у вас запутанные или плохо настроенные сети, вы можете получать один и тот же пакет несколько раз. Просто один на один, потому что люди склонны забывать это! TCP не гарантирует доставку , он просто гарантирует, что если он сможет доставить пакеты, они будут в том же порядке, в котором они были отправлены. Кстати, я часто вижу, как люди приравнивают надежность / порядок доставки к повторным передачам TCP. Эти «эксперты» скажут вам, что для преодоления ошибок передачи по UDP, вы будете переопределять TCP (плохо), и поэтому вы могли бы также использовать TCP. Это неправда. Существуют и другие методы восстановления после ошибок, которые не страдают задержкой или экспоненциально сниженной пропускной способностью в результате небольших, но ненулевых частот ошибок. TCP также гарантирует, что вы будете знать, если пункт назначения не получил пакеты.Это один из моих любимых вопросов. UDP так неправильно поняли.
В ситуациях, когда вы действительно хотите быстро получить простой ответ на другой сервер, UDP работает лучше всего. Как правило, вы хотите, чтобы ответ был в одном ответном пакете, и вы готовы внедрить собственный протокол для надежности или повторной отправки. DNS является идеальным описанием этого варианта использования. Стоимость настройки соединения слишком высока (однако DNS также поддерживает режим TCP).
Другой случай - когда вы доставляете данные, которые могут быть потеряны, потому что поступающие более новые данные заменят эти предыдущие данные / состояние. На ум приходят данные о погоде, потоковое видео, сервис биржевых котировок (не используется для реальной торговли) или игровые данные.
Другой случай, когда вы управляете огромным количеством состояний и хотите избежать использования TCP, потому что ОС не может обработать такое количество сеансов. Это редкий случай сегодня. Фактически, в настоящее время существуют пользовательские стеки TCP, которые можно использовать для того, чтобы разработчик приложений мог иметь более точный контроль над ресурсами, необходимыми для этого состояния TCP. До 2003 года UDP был действительно единственной игрой в городе.
Еще один случай - многоадресный трафик. UDP может быть многоадресным для нескольких хостов, тогда как TCP вообще не может этого делать.
Спасибо за интересный ответ. У нас есть сервер, который в настоящее время выполняет все в UDP (требование высокой пропускной способности), что нормально, потому что на самом деле есть один переход (маршрутизация отключена, . ), но мы заметили, что переупорядочение пакетов может стать проблемой на некоторых неисправных сетевых картах. Какой пользовательский стек TCP (или какой-либо другой поток, управляемый в пользовательском режиме) вы предлагаете? @dashesy - вы можете избавиться от требования заказа? Есть ли монотонно увеличивающееся число внутри полезной нагрузки, которое вы можете использовать? Если это так, вам не нужен полноценный стек TCP пользователя. @ drudru- да есть порядковый номер, мне, возможно, придется буферизоваться и де-джиттер сам. Спасибо, исключение еще одного варианта всегда здорово.Если пакет TCP потерян, он будет отправлен повторно. Это не удобно для приложений, которые полагаются на данные, обрабатываемые в определенном порядке в реальном времени.
Примеры включают потоковое видео и особенно VoIP (например, Skype ). В этих случаях, однако, отброшенный пакет не имеет большого значения: наши чувства не идеальны, поэтому мы можем даже не заметить. Вот почему эти типы приложений используют UDP вместо TCP.
Я думаю, что у вас есть это задом наперед. TCP переупорядочивает пакеты так, чтобы данные доставлялись в отправленном порядке. UDP не переупорядочивает и доставляет данные в том порядке, в котором он их получил. UDP не гарантирует порядок, однако вы можете нумеровать пакеты и переупорядочивать их после получения. @ Stephan202: Думаю, мне не следует соглашаться с тем, чтобы не замечать пропущенные пакеты в Skype ;-) @ Кугель: Просто знайте, что вы можете реализовать новый стек TCP. Вряд ли вы справитесь с этой задачей лучше, чем ОС. @erikkallen: Если бы кто-то использовал UDP для реализации протокола более высокого уровня с теми же требованиями, которым был разработан протокол TCP, вряд ли он будет намного лучше, чем существующие протоколы. С другой стороны, некоторые приложения выигрывают от добавления в протокол нескольких функций, которые оболочка UDP могла бы обрабатывать лучше, чем TCP.«Ненадежность» UDP - это формализм. Передача не абсолютно гарантирована. На практике они почти всегда проходят. Они просто не признаются и повторяются после тайм-аута.
Затраты на согласование сокета TCP и квитирование TCP-пакетов огромны. Действительно огромный. Нет заметных накладных расходов UDP.
«На практике они почти всегда проходят». Сильно зависит от более низкого уровня надежности сети кроме того, есть ли разница между планированием «нескольких» потерь пакетов и «слишком больших» потерь пакетов? потеря есть потеря. Вы все равно должны планировать это.Я работаю над продуктом, который поддерживает как UDP (IP), так и TCP / IP связь между клиентом и сервером. Он начался с IPX более 15 лет назад с поддержкой IP, добавленной 13 лет назад. Мы добавили поддержку TCP / IP 3 или 4 года назад. Подходят дикие предположения: отношение кода UDP к TCP, вероятно, составляет около 80/20. Продукт является сервером базы данных, поэтому надежность имеет решающее значение. Мы должны решить все проблемы, связанные с UDP (потеря пакетов, удвоение пакетов, порядок пакетов и т. Д.), Уже упомянутые в других ответах. Есть редко какие-либо проблемы, но они иногда случаются и поэтому должны быть обработаны. Преимущество поддержки UDP состоит в том, что мы можем немного настроить его для нашего собственного использования и немного повысить его производительность.
Каждая сеть будет отличаться, но протокол связи UDP, как правило, немного быстрее для нас. Скептически настроенный читатель справедливо спросит, правильно ли мы все реализовали Кроме того, что вы можете ожидать от парня с 2-значным повторением? Тем не менее, я только что провела испытание из любопытства. Тест прочитал 1 миллион записей (выберите * из sometable). Я устанавливаю количество записей, которое нужно возвращать с каждым индивидуальным клиентским запросом, равным 1, 10, а затем 100 (три запуска теста с каждым протоколом). Сервер находился всего в двух прыжках по 100 Мбит локальной сети. Цифры, похоже, согласуются с тем, что другие находили в прошлом (в большинстве случаев UDP работает примерно на 5% быстрее). Общее время в миллисекундах было следующим для этого конкретного теста:
- 1 запись
- IP: 390 760 мс
- TCP: 416 903 мс
- 10 записей
- IP: 91,707 мс
- TCP: 95 662 мс
- 100 записей
- IP: 29,664 мс
- TCP: 30 968 мс
Общий объем передаваемых данных был примерно одинаковым для IP и TCP. У нас есть дополнительные накладные расходы на связь UDP, потому что у нас есть некоторые из тех вещей, которые вы получаете «бесплатно» с TCP / IP (контрольные суммы, порядковые номера и т. Д.). Например, Wireshark показал, что запрос следующего набора записей составляет 80 байтов с UDP и 84 байта с TCP.
Что если бы вы разработали его только для TCP и купили бы более качественное оборудование, а не в 5 раз больше усилий по программированию? Спасибо за конкретные цифры! Улучшение на 5% немного разочаровывает сложностью, которую он добавляет. Вероятно, 5%, потому что отправляется в локальной сети (две надежды)? Я думаю, что чем дальше, тем выше разница.Поскольку UDP не использует управление перегрузкой, он может быть и быстрее, и испытывать меньшую задержку, поскольку он не будет стремиться максимизировать буферы вплоть до точки отбрасывания, то есть UDP-пакеты тратят меньше времени в буферах и добираются быстрее с меньшей задержкой. Поскольку UDP не использует управление перегрузкой, а TCP использует, он может отобрать емкость у TCP, которая уступает потокам UDP.
В результате UDP может:
Таким образом, UDP можно использовать для любого типа приложений, которые может использовать TCP, если вы также внедрили надлежащий механизм повторной передачи. UDP может быть очень быстрым, иметь меньшую задержку, не подвержен перегрузкам на основе соединения, передает дейтаграммы фиксированного размера и может использоваться для многоадресной рассылки.
Когда сети становятся достаточно перегруженными, чтобы вызвать потерю пакетов, TCP пытается минимизировать его влияние на других пользователей сети, в то время как многие реализации на основе UDP этого не делают. Это позволяет им захватить большую долю уменьшающегося пирога, но также уменьшает общий объем доступного периода полезной полосы пропускания (например, вследствие ненужной повторной передачи в случаях, когда данные фактически будут доставлены, но отправитель не поймет этого) Прежде всего, спасибо за отличный ответ, я действительно многому научился от него! Но у меня есть вопрос: не происходит ли сегментация на уровне 3 (IP) из-за ограничений адаптера Ethernet для всех пакетов, полученных с уровня 4 (как TCP, так и UDP)? Вы имеете в виду любой другой вид сегментации, который происходит в TCP, но не происходит в UDP? Буду очень признателен, если вы мне это объясните. @Freezy. Вы правы, фрагментация пакетов, которые превышают MTU канала (уровень 2), происходит на уровне 3-IP. Однако TCP - это потоковый протокол, который обрабатывает данные как поток байтов. TCP отправляет свои данные в сегментах, чтобы соответствовать внутренним IP-пакетам, размер которых соответствует MSS, поэтому сегментация также происходит в TCP. Сколько данных TCP помещает в сегмент или сколько данных читает ваш сокет, зависит от многих факторов; это может быть 1 байт или байты MSS. При использовании UDP получатель всегда получает точное количество байтов, отправленных передатчиком, если пакет не потерян в пути.UDP имеет меньше накладных расходов и хорош для таких вещей, как потоковая передача данных в реальном времени, таких как аудио или видео, или в любом случае, когда все в порядке, если данные потеряны.
UDP является протоколом без установления соединения и используется в таких протоколах, как SNMP и DNS, в которых пакеты данных, поступающие не по порядку, являются приемлемыми и имеет значение немедленная передача пакета данных.
Он используется в SNMP, так как управление сетью часто должно выполняться, когда сеть находится в состоянии стресса, то есть когда надежная передача данных, контролируемая перегрузкой, затруднена.
Он используется в DNS, поскольку он не включает установление соединения, что позволяет избежать задержек при установлении соединения.
TCP имеет блокировку заголовка очереди, поскольку он гарантирует полную и упорядоченную доставку, поэтому, когда пакет теряется при передаче, он должен ждать повторной передачи отсутствующего пакета, тогда как UDP доставляет пакеты приложению по мере их поступления. включая дубликаты и без какой-либо гарантии того, что пакет прибыл вообще или в каком порядке он поступает (на самом деле это IP-адрес с добавленными номерами портов и (необязательно) контрольной суммой полезной нагрузки), но это хорошо для телефонии, например, где он обычно просто не имеет значения, когда пропадают несколько миллисекунд звука, но задержка очень раздражает, поэтому вам не нужно повторять передачу, вы просто отбрасываете любые дубликаты, сортируете переупорядоченные пакеты в правильном порядке для нескольких сотен миллисекунд буфера дрожания и если пакеты не появляются вовремя или вообще, они просто пропускаются,возможно интерполируется там, где поддерживается кодеком.
Кроме того, основной частью TCP является управление потоком, чтобы обеспечить максимально возможную пропускную способность, но без перегрузки сети (что является своего рода избыточным, поскольку перегруженная сеть будет отбрасывать ваши пакеты, что означает, что вам придется делать это). повторная передача, что ухудшает пропускную способность), UDP не имеет ничего из этого - что имеет смысл для таких приложений, как телефония, поскольку телефонии с данным кодеком требуется определенная пропускная способность, вы не можете «замедлить ее», а также дополнительная пропускная способность не делает звонок быстрее
В дополнение к приложениям реального времени / с малой задержкой, UDP имеет смысл для действительно небольших транзакций, таких как поиск DNS, просто потому, что у него нет установления соединения TCP и накладных расходов на разрыв, как с точки зрения задержки, так и с точки зрения использования пропускной способности. Если ваш запрос меньше, чем типичный MTU, и ответ, скорее всего, тоже есть, вы можете выполнить его в один прием, без необходимости сохранять какое-либо состояние на сервере, а также управлять потоками и упорядочивать их, и все это, вероятно, не особенно полезно. для таких целей либо.
И затем, конечно, вы можете использовать UDP для создания своих собственных замен TCP, но это, вероятно, не очень хорошая идея без некоторого глубокого понимания динамики сети, современные алгоритмы TCP довольно сложны.
Кроме того, я думаю, следует упомянуть, что существует больше, чем UDP и TCP, такие как SCTP и DCCP. Единственная проблема в настоящее время состоит в том, что Интернет (IPv4) полон шлюзов NAT, которые делают невозможным использование протоколов, отличных от UDP и TCP, в приложениях конечного пользователя.
Читайте также: