Протоколы tcp udp. Протокол UDP

Протоколы TCP и UDP

TCP- Transmission Control Protocol

Обмен данными, ориентированный на соединения, может использовать надежную связь, для обеспечения которой протокол уровня 4 посылает подтверждения о получении данных и запрашивает повторную передачу, если данные не получены или искажены. Протокол TCP использует именно такую надежную связь. TCP используется в таких прикладных протоколах, как HTTP, FTP, SMTP и Telnet.

Протокол TCP требует, чтобы перед отправкой сообщения было открыто соединение. Серверное приложение должно выполнить так называемое пассивное открытие (passive open) , чтобы создать соединение с известным номером порта, и, вместо того чтобы отправлять вызов в сеть, сервер переходит в ожидание поступления входящих запросов. Клиентское приложение должно выполнить активное открытие (active open) , отправив серверному приложению синхронизирующий порядковый номер (SYN), идентифицирующий соединение. Клиентское приложение может использовать динамический номер порта в качестве локального порта.

Сервер должен отправить клиенту подтверждение (ACK) вместе с порядковым номером (SYN) сервера. В свою очередь клиент отвечает АСК, и соединение устанавливается.

После этого может начаться процесс отправки и получения сообщений. При получении сообщения в ответ всегда отправляется сообщение АСК. Если до получения АСК отправителем истекает тайм-аут, сообщение помещается в очередь на повторную передачу.

Поля заголовка TCP перечислены в следующей таблице:

Заголовок TCP
Поле Длина Описание
Порт источника 2 байта Номер порта источника
Порт назначения 2 байта Номер порта назначения
Последовательный номер 4 байта Последовательный номер генерируется источником и используется назначением, чтобы переупорядочить пакеты для создания исходного сообщения и отправить подтверждение источнику.
Номер подтверждения 4 байта Если установлен бит АСК поля "Управление", в данном поле содержится следующий ожидаемый последовательный номер.
Смещение данных 4 бита Информация о начале пакета данных.
Резерв 6 битов Резервируются для будущего использования.
Управление 6 битов Биты управления содержат флаги, указывающие, верны ли поля подтверждения (АСК), указателя срочности (URG), следует ли сбрасывать соединение (RST), послан ли синхронизирующий последовательный номер (SYN) и т. д.
Размер окна 2 байта В этом поле указывается размер приемного буфера. Используя подтверждающие сообщения, получатель может информировать отправителя о максимальном размере данных, которые тот может отправить.
Контрольная сумма 2 байта Контрольная сумма заголовка и данных; по ней определяется, был ли искажен пакет.
Указатель срочности 2 байта В этом поле целевое устройство получает информацию о срочности данных.
Опции переменная Необязательные значения, которые указываются при необходимости.
Дополнение переменная В поле дополнения добавляется столько нулей, чтобы заголовок заканчивался на 32-битной границе.

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

Протокол TCP имеет встроенную возможность надежной доставки. Если сообщение не отправлено корректно, мы получим сообщение об ошибке. Протокол TCP определен в RFC 793.

UDP - User Datagram Protocol

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

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

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

Однонаправленное (unicast) сообщение отправляется из одного узла только в один другой узел. Это также называется связью "точка-точка". Протокол TCP поддерживает лишь однонаправленную связь. Если серверу нужно с помощью TCP взаимодействовать с несколькими клиентами, каждый клиент должен установить соединение, поскольку сообщения могут отправляться только одиночным узлам.

Широковещательная передача (broadcast) означает, что сообщение отправляется всем узлам сети. Групповая рассылка (multicast) - это промежуточный механизм: сообщения отправляются выбранным группам узлов.

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

Протокол UDP

User Datagram Protocol (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 могут получать более одного сообщения в каждый промежуток времени. В некоторых случаях сервисы TCP и UDP могут использовать одни и те же номера портов, например 7 (Echo) или 23 (Telnet).

UDP использует следующие известные порты:

Перечень портов UDP и TCP поддерживается агентством IANA (Internet Assigned Numbers Authority) .

IP-адреса

Дейтаграмма IP состоит из 32-битных IP-адресов источника и назначения. IP-адрес назначения задает конечную точку для дейтаграммы UDP, а 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 не имеет поддержки сеансов из-за своей природы, не ориентированной на соединения.

    Надежность . UDP не гарантирует, что адресату будет доставлена только одна копия данных. Чтобы отправить конечной системе большой объем данных, UDP разбивает его на небольшие части. UDP не гарантирует, что эти части будут доставлены по назначению в том же порядке, в каком они создавались в источнике. Напротив, TCP вместе с номерами портов использует порядковые номера и регулярно отправляемые подтверждения, гарантирующие упорядоченную доставку данных.

    Безопасность . 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 потребляет меньше пропускной способности сети.

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

Привет, меня зовут Гленн Фидлер и я приветствую вас в первой статье из моей онлайн-книги “Сетевое программирование для разрабочиков игр”.

В этой статье мы начнем с самых базовых аспектов сетевого программирования - приема и передачи данных по сети. Прием и передача данных - это основная и наиболее простая часть из всего круга задач, которыми занимаются сетевые программисты, но часто бывает сложно определить, каким путем лучше двигаться. Уделите этой части достаточно внимания - если у вас останется непонимание, то это может привести к ужасным последствиям для вашей многопользовательской игры в дальнейшем!

Вы, скорее всего, уже что-нибудь слышали о сокетах, и, возможно, знаете, что они делятся на два основных типа - TCP и UDP. Первое, что нужно решить при разработке многопользовательской игры - это какой тип сокетов использовать - TCP, UDP, или оба?

Выбор типа сокетов полностью зависит от жанра игры, которую разрабатываете. В данном цикле статей я буду считать, что вы пишете игру в стиле action - наподобие Halo, Battlefield 1942, Quake, Unreal, CounterStrike, Team Fortress и т.п.

Теперь мы более подробно рассмотрим свойства каждого типа сокетов (учитывая тот факт, что мы разрабатыватаем игру в стиле action), и немного углубимся в детали работы сети интернет. После подробного обзора правильный вариант станет очевиден!

TCP расшифровывается как “transmission control protocol” (протокол контроля передачи), а IP - как “internet protocol”. Вместе они лежат в основе практически всего, что вы делаете в сети, начиная от просмотра веб-страниц и кончая общением в IRC и электронной почтой - все это работает на основе TCP/IP.

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

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

Еще разок - все просто, как обычная запись или чтение из файла. Элементарно, Ватсон!

Но такая простота в обращении совершенно отличается от того, что на самом деле происходит «под капотом», на более низком уровне - уровне протокола IP.

На этом уровне нет понятия соединения - вместо этого отдельные пакеты передаются от одного компьютера к другому. Можно представить этот процесс как передачу записки от одного человека к другому в комнате, полной народу: в конце концов записка попадает к кому надо, но при этом пройдя через множество рук.

При этом нет никакой гарантии того, что записка дойдет до адресата. Отправитель просто отправляет записку в надежде, что она дойдет, но при этом даже не знает, дошло ли послание или нет - до тех пор, пока получатель не решит написать в ответ.
Естественно, в реальности все немного сложнее, поскольку компьютер-отправитель не знает точную последовательность компьютеров в сети, через которые надо передать пакет, чтобы он добрался как можно быстрее. Иногда IP передает несколько копий одного и того же пакета, которые могут идти до адресата разными путями - и, скорее всего, дойдут в разное время.

А что, если мы захотим пересылать информацию между компьютерами не в стиле чтения/записи в файл, а непосредственно отправляя и получая отдельные пакеты?

Что ж, мы можем сделать это, используя UDP. UDP расшифровывается как “user datagram protocol” (протокол пользовательских датаграмм), и он работает поверх IP (как и TCP), но вместо добавления кучи функциональности он представляет собой лишь небольшую надстройку над IP.

Используя UDP, мы можем отослать пакет по определенному IP адресу (к примеру, 112.140.20.10) и порту (к примеру, 52423), и он будет передаваться от компьютера к компьютеру, пока не достигнет цели (или не потеряется по пути).

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

Протокол UDP не гарантирует доставку данных. На практике большинство пакетов, конечно, доходят, но всегда имеются потери около 1-5%, а иногда бывают периоды времени, в которые пакеты вообще не доходят (помните, что между отправителем и получателем могут находиться тысячи компьютеров, на любом из которых что-то может отказать или сломаться).

Также UDP не гарантирует порядок доставки пакетов. Вы можете отправить пять пакетов по порядку - 1, 2, 3, 4, 5 - а прийти они могут совершенно в другом порядке - к примеру, 3, 1, 2, 5, 4. Опять же, на практике, они скорее всего придут в правильном порядке в большинстве случаев, но полагаться на это нельзя!

Наконец, хоть UDP и ничего особо не добавляет к IP, одну вещь он все-таки гарантирует. Если вы пересылаете пакет, то он либо дойдет полностью, либо не дойдет вообще. Так, если вы пересылаете пакет в 256 байт другому компьютеру, то он не может получить только первые 100 байт от пакета - он обязательно должен получить все 256 байт. Это реально единственная вещь, которую гарантирует протокол UDP - все остальное ложится на ваши плечи.

Итак, нам нужно решить - использовать TCP или UDP сокеты? Давайте взглянем на их свойства:

  • Использует принцип соединений
  • Гарантирует доставку и очередность
  • Автоматически разбивает информацию на пакеты
  • Следит за тем, чтобы не пересылать данные слишком интенсивно (контроль потока данных)
  • Легко использовать - как запись/чтение из файла
UDP:
  • Не использует принцип соединений - придется реализовывать это вручную
  • Не гарантирует доставку и порядок доставки пакетов - они могут дойти в неправильном порядке, с дубликатами, или вообще не дойти!
  • Нужно вручную разбивать данные на пакеты и отправлять их
  • Нужно следить за тем, чтобы не пересылать данные слишком интенсивно
  • Если пакет потеряется, то нужно как-то это отследить, и в случае необходимости переслать его заново
С таким списком решение кажется очевидным - TCP реализует всю необходимую нам функциональность и его проще использовать, тогда как использование UDP обещает геморрой с написанием всего на свете вручную, с нуля. Значит, используем TCP, да?

А вот и нет.

Использовать TCP - это наверное, худшая ошибка, которую можно совершить, разрабатывая многопользовательскую игру. Чтобы понять почему, давайте разберемся, что делает TCP таким простым в использовании!

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

Итак, как же он это делает?

Во-первых, TCP использует абстракцию потока данных - вы можете просто записывать байты данных в этот поток, и TCP позаботится о том, чтобы они дошли до адресата. Так как протокол IP передает данные пакетами, а TCP работает поверх IP, TCP должен разбивать поток входных данных пользователя на отдельные пакеты. Таким образом, внутри TCP некоторая логика собирает данные в очередь, и, когда их накапливается достаточно много, она формирует пакет и отправляет его адресату.

Такое поведение может стать проблемой для нашей многопользовательской игры, если нужно передавать очень маленькие пакеты. Может случиться так, что TCP решит не передавать наши данные, пока их не накопится достаточно, чтобы сформировать пакет определенного размера (скажем, больше ста байт). И это - большая проблема, потому что необходимо передавать данные с клиента (нажатия клавиш игрока) на сервер как можно быстрее, и если при этом будут возникать задержки из-за буферизации данных протоколом, то для игрока на клиентской стороне игра будет происходить далеко не самым приятным образом. При этом обновление объектов игры будет происходить с задержкой и редко - тогда как нам нужно делать обновление объектов вовремя и часто.

В TCP есть опция, призванная исправить это - “TCP_NODELAY”. Она говорит протоколу, чтобы он не ждал накопления данных в очереди на отправку, а отсылал их сразу.

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

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

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

Но что будет, если один из пакетов не дойдет? Или если пакеты придут не по порядку, или с дубликатами?

Если особо не углубляться в детали работы TCP (а это реально очень сложная тема - можете почитать в TCP/IP Illustrated), процесс выглядит так: TCP отправляет пакет, определяет, что пакет не дошел, и заново отправляет тот же пакет адресату. Дублирующиеся пакеты отсеиваются на стороне адресата, а пакеты, пришедшие не по порядку - переупорядочиваются, чтобы все было как надо - надежно и по порядку.

Проблема заключается в том, что когда TCP таким образом “синхронизирует” поток данных, в случае потери пакета передача останавливается до тех пор, пока потерянный пакет не будет отправлен заново (и получен адресатом). Если во время ожидания придут новые данные, они будут поставлены в очередь, и вы не сможете прочитать их, пока не дойдет тот самый потерянный пакет. Сколько времени занимает посылка пакета заново? Она занимает как минимум время, равное времени прохождения пакета туда и обратно (когда TCP определяет, какой пакет надо отправить заново), плюс время на повторную доставку потерянного пакета. Так что, если пинг между компьютерами составляет 125 мс, повторная передача пакета займет примерно одну пятую секунды, а в худшем случае - до полсекунды (представьте, если вдруг заново отправленный пакет тоже потеряется). Веселуха!

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

Рассмотрим простой пример многопользовательской игры, например, 3d-шутер. Сетевая часть в игре построена очень просто: каждую итерацию цикла игры клиент посылает на сервер описание всех действий игрока (нажатые клавиши, положение мыши и т.п.), и каждую итерацию сервер обрабатывает эти данные, обновляет модель игрового мира и посылает обратно клиенту текущие позиции объектов мира, чтобы тот отрисовал игроку новый кадр.

Итак, в нашей игре, если пакет будет потерян при передаче по сети, игра останавливается и ждет, пока пакет не будет доставлен заново. На клиентской стороне игровые объекты замирают, и на сервере игроки также не могут двигаться или стрелять, так как сервер не может принимать новые пакеты. Когда потерянный пакет наконец доходит, в нем содержится уже устаревшая информация, которая уже является неактуальной. К тому же после этого приходят и все те пакеты, которые накопились в очереди за время ожидания, и их всех нужно обработать за одну итерацию цикла. Полная неразбериха!

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

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

Но подождите! Почему я не могу использовать и UDP, и TCP вместе?

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

Конечно, велико искушение использовать UDP для передачи данных пользовательского ввода и состояния мира, а TCP - для тех данных, которые должны быть гарантированно доставлены. Возможно, вы даже думаете, что можно сделать несколько “потоков” команд - например, один для загрузки уровней, другой - для команд AI. Вы думаете: “Мне не нужно, чтобы команды AI ждали в очереди, если потеряется пакет с данными для загрузки уровня, ведь они же совершенно не связаны!”. В данном случае вы правы, и вы можете решить создать по TCP сокету на каждый поток команд.

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

UDP использует простую модель передачи, без неявных "рукопожатий" для обеспечения надежности, упорядочивания или целостности данных. Таким образом, UDP предоставляет ненадежный сервис, и датаграммы могут прийти не по порядку, дублироваться или вовсе исчезнуть без следа. UDP подразумевает, что проверка ошибок и исправление либо не необходимы, либо должны исполняться в приложении. Чувствительные ко времени приложения часто используют UDP, так как предпочтительнее сбросить пакеты, чем ждать задержавшиеся пакеты, что может оказаться невозможным в системах реального времени . При необходимости исправления ошибок на сетевом уровне интерфейса приложение может задействовать TCP или SCTP , разработанные для этой цели.

Природа UDP как протокола без сохранения состояния также полезна для серверов, отвечающих на небольшие запросы от огромного числа клиентов, например DNS и потоковые мультимедийные приложения вроде IPTV , Voice over IP , протоколы туннелирования IP и многие онлайн-игры .

Служебные порты

UDP не предоставляет никаких гарантий доставки сообщения для протокола верхнего уровня и не сохраняет состояния отправленных сообщений. По этой причине UDP иногда называют Unreliable Datagram Protocol (англ. - Ненадежный протокол датаграмм).

Перед расчетом контрольной суммы UDP-сообщение дополняется в конце нулевыми битами до длины, кратной 16 битам (псевдозаголовок и добавочные нулевые биты не отправляются вместе с сообщением). Поле контрольной суммы в UDP-заголовке во время расчета контрольной суммы отправляемого сообщения принимается нулевым.

Для расчета контрольной суммы псевдозаголовок и UDP-сообщение разбивается на слова (1 слово = 2 байта (октета) = 16 бит). Затем рассчитывается поразрядное дополнение до единицы суммы всех слов с поразрядным дополнением. Результат записывается в соответствующее поле в UDP-заголовке.

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

При получении сообщения получатель считает контрольную сумму заново (уже учитывая поле контрольной суммы), и, если в результате получится двоичное число из шестнадцати единиц (то есть 0xffff), то контрольная сумма считается сошедшейся. Если сумма не сходится (данные были повреждены при передаче), датаграмма уничтожается.

Пример расчёта контрольной суммы

Для примера рассчитаем контрольную сумму нескольких 16-битных слов: 0x398a, 0xf802, 0x14b2, 0xc281 . Находим их сумму с поразрядным дополнением.
0x398a + 0xf802 = 0x1318c → 0x318d
0x318d + 0x14b2 = 0x0463f → 0x463f
0x463f + 0xc281 = 0x108c0 → 0x08c1
Теперь находим поразрядное дополнение до единицы полученного результата:

0x08c1 = 0000 1000 1100 0001 → 1111 0111 0011 1110 = 0xf73e или, иначе - 0xffff − 0x08c1 = 0xf73e . Это и есть искомая контрольная сумма.

При вычислении контрольной суммы опять используется псевдозаголовок, имитирующий реальный IPv6-заголовок:

Биты 0 – 7 8 – 15 16 – 23 24 – 31
0 Адрес источника
32
64
96
128 Адрес получателя
160
192
224
256 Длина UDP
288 Нули Следующий заголовок
320 Порт источника Порт получателя
352 Длина Контрольная сумма
384+
Данные

Адрес источника такой же, как и в IPv6-заголовке. Адрес получателя - финальный получатель; если в IPv6-пакете не содержится заголовка маршрутизации (Routing), то это будет адрес получателя из IPv6-заголовка, в противном случае, на начальном узле, это будет адрес последнего элемента заголовка маршрутизации, а на узле-получателе - адрес получателя из IPv6-заголовка. Значение "Следующий заголовок" равно значению протокола - 17 для UDP. Длина UDP - длина UDP-заголовка и данных.

Надежность и решения проблемы перегрузок

Из-за недостатка надежности, приложения UDP должны быть готовыми к некоторым потерям, ошибкам и дублированиям. Некоторые из них (например, TFTP) могут при необходимости добавить элементарные механизмы обеспечения надежности на прикладном уровне.

Но чаще такие механизмы не используются UDP-приложениями и даже мешают им. Потоковые медиа , многопользовательские игры в реальном времени и VoIP - примеры приложений, часто использующих протокол UDP. В этих конкретных приложениях потеря пакетов обычно не является большой проблемой. Если приложению необходим высокий уровень надежности, то можно использовать другой протокол (TCP) или erasure codes.

Более серьезной потенциальной проблемой является то, что в отличие от TCP, основанные на UDP приложения не обязательно имеют хорошие механизмы контроля и избежания перегрузок. Чувствительные к перегрузкам UDP-приложения, которые потребляют значительную часть доступной пропускной способности, могут поставить под угрозу стабильность в Интернете.

Сетевые механизмы были предназначены для того, чтобы свести к минимуму возможные эффекты от перегрузок при неконтролируемых, высокоскоростных нагрузках. Такие сетевые элементы, как маршрутизаторы, использующие пакетные очереди и техники сброса, часто являются единственным доступным инструментом для замедления избыточного UDP-трафика. DCCP (англ. Datagram Congestion Control Protocol - протокол контроля за перегрузками датаграмм) разработан как частичное решение этой потенциальной проблемы с помощью добавления конечному хосту механизмов для отслеживания перегрузок для высокоскоростных UDP-потоков вроде потоковых медиа.

Приложения

Многочисленные ключевые Интернет-приложения используют UDP, в их числе - DNS (где запросы должны быть быстрыми и состоять только из одного запроса, за которым следует один пакет ответа), Простой Протокол Управления Сетями (SNMP), Протокол Маршрутной Информации (RIP), Протокол Динамической Конфигурации Узла (DHCP).

Голосовой и видеотрафик обычно передается с помощью UDP. Протоколы потокового видео в реальном времени и аудио разработаны для обработки случайных потерь пакетов так, что качество лишь незначительно уменьшается вместо больших задержек при повторной передаче потерянных пакетов. Поскольку и TCP, и UDP работают с одной и той же сетью, многие компании замечают, что недавнее увеличение UDP-трафика из-за этих приложений реального времени мешает производительности TCP-приложений вроде систем баз данных или бухгалтерского учета . Так как и бизнес-приложения, и приложения в реальном времени важны для компаний, развитие качества решений проблемы некоторыми рассматривается в качестве важнейшего приоритета.

Сравнение UDP и TCP

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

  • Надежность - TCP управляет подтверждением, повторной передачей и тайм-аутом сообщений. Производятся многочисленные попытки доставить сообщение. Если оно потеряется на пути, сервер вновь запросит потерянную часть. В TCP нет ни пропавших данных, ни (в случае многочисленных тайм-аутов) разорванных соединений.
  • Упорядоченность - если два сообщения последовательно отправлены, первое сообщение достигнет приложения-получателя первым. Если участки данных прибывают в неверном порядке, TCP отправляет неупорядоченные данные в буфер до тех пор, пока все данные не могут быть упорядочены и переданы приложению.
  • Тяжеловесность - TCP необходимо три пакета для установки сокет-соединения перед тем, как отправить данные. TCP следит за надежностью и перегрузками.
  • Потоковость - данные читаются как поток байтов , не передается никаких особых обозначений для границ сообщения или сегментов.

UDP - более простой, основанный на сообщениях протокол без установления соединения. Протоколы такого типа не устанавливают выделенного соединения между двумя хостами. Связь достигается путем передачи информации в одном направлении от источника к получателю без проверки готовности или состояния получателя. Однако, основным преимуществом UDP над TCP являются приложения для голосовой связи через интернет-протокол (Voice over IP, VoIP), в котором любое "рукопожатие" помешало бы хорошей голосовой связи. В VoIP считается, что конечные пользователи в реальном времени предоставят любое необходимое подтверждение о получении сообщения.

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

Ссылки на RFC

  • RFC 768 – Протокол Пользовательских Датаграмм
  • RFC 2460 – Интернет протокол, спецификация версии 6 (IPv6)
  • RFC 2675 - IPv6 Jumbograms
  • RFC 4113 – Management Information Base for the UDP
  • RFC 5405 – Unicast UDP Usage Guidelines for Application Designers

См. также

Ссылки

  • Kurose, J. F.; Ross, K. W. (2010). Computer Networking: A Top-Down Approach (5th ed.). Boston, MA: Pearson Education. ISBN 978-0-13-136548-3 .
  • Forouzan, B.A. (2000). TCP/IP: Protocol Suite, 1st ed. New Delhi, India: Tata McGraw-Hill Publishing Company Limited.
  • [email protected]. "UDP Protocol Overview". Ipv6.com. Retrieved 17 August 2011.
  • Clark, M.P. (2003). Data Networks IP and the Internet, 1st ed. West Sussex, England: John Wiley & Sons Ltd.
  • Postel, J. (August 1980). RFC 768 : User Datagram Protocol. Internet Engineering Task Force. Retrieved from http://tools.ietf.org/html/rfc768
  • Deering S. & Hinden R. (December 1998). RFC 2460 : Internet Protocol, Version 6 (IPv6) Specification. Internet Engineering Task Force. Retrieved from http://tools.ietf.org/html/rfc2460
  • "The impact of UDP on Data Applications". Networkperformancedaily.com. Retrieved 17 August 2011.
  • Д. Комер. Межсетевой обмен с помощью TCP/IP. Глава 11. Протокол UDP.

Всем привет сегодня расскажу чем отличается протокол TCP от UDP. Протоколы транспортного уровня, следующие в иерархии за IP, используются для передачи данных между прикладными процессами, реализующимися в сетевых узлах. Пакет данных, поступивший от одного компьютера другому через Интернет, должен быть передан процессу-обработчику, и именно по конкретному назначению. Транспортный уровень принимает на себя ответственность за это. На этом уровне два основных протокола – TCP и UDP.

Что означают TCP и UDP

TCP – транспортный протокол передачи данных в сетях TCP/IP, предварительно устанавливающий соединение с сетью.

UDP – транспортный протокол, передающий сообщения-датаграммы без необходимости установки соединения в IP-сети.

Напоминаю, что оба протокола работают на транспортном уровне модели OSI или TCP/IP, и понимание того чем они отличаются очень важно.

Разница между протоколами TCP и UDP

Разница между протоколами TCP и UDP – в так называемой “гарантии доставки”. TCP требует отклика от клиента, которому доставлен пакет данных, подтверждения доставки, и для этого ему необходимо установленное заранее соединение. Также протокол TCP считается надежным, тогда как UDP получил даже именование “протокол ненадежных датаграмм. TCP исключает потери данных, дублирование и перемешивание пакетов, задержки. UDP все это допускает, и соединение для работы ему не требуется. Процессы, которым данные передаются по UDP, должны обходиться полученным, даже и с потерями. TCP контролирует загруженность соединения, UDP не контролирует ничего, кроме целостности полученных датаграмм.

С другой стороны, благодаря такой не избирательности и бесконтрольности, UDP доставляет пакеты данных (датаграммы) гораздо быстрее, потому для приложений, которые рассчитаны на широкую пропускную способность и быстрый обмен, UDP можно считать оптимальным протоколом. К таковым относятся сетевые и браузерные игры, а также программы просмотра потокового видео и приложения для видеосвязи (или голосовой): от потери пакета, полной или частичной, ничего не меняется, повторять запрос не обязательно, зато загрузка происходит намного быстрее. Протокол TCP, как более надежный, с успехом применяется даже в почтовых программах, позволяя контролировать не только трафик, но и длину сообщения и скорость обмена трафиком.

Давайте рассмотрим основные отличия tcp от udp.

  1. TCP гарантирует доставку пакетов данных в неизменных виде, последовательности и без потерь, UDP ничего не гарантирует.
  2. TCP нумерует пакеты при передаче, а UDP нет
  3. TCP работает в дуплексном режиме, в одном пакете можно отправлять информацию и подтверждать получение предыдущего пакета.
  4. TCP требует заранее установленного соединения, UDP соединения не требует, у него это просто поток данных.
  5. UDP обеспечивает более высокую скорость передачи данных.
  6. TCP надежнее и осуществляет контроль над процессом обмена данными.
  7. UDP предпочтительнее для программ, воспроизводящих потоковое видео, видеофонии и телефонии, сетевых игр.
  8. UPD не содержит функций восстановления данных

Примерами UDP приложений, например можно привести, передачу DNS зон, в Active Directory, там не требуется надежность. Очень часто такие вопросы любят спрашивать на собеседованиях, так, что очень важно знать tcp и udp отличия.

Заголовки TCP и UDP

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

Заголовок UDP

  • 16 битный порт источника > Указание порта источника для UDP необязательно. Если это поле используется, получатель может отправить ответ этому порту.
  • 16 битный порт назначения > Номер порта назначения
  • 16 битная длина UDP > Длина сообщения, включая заголовок и данные.
  • 16 битная контрольная сумма > Контрольная сумма заголовка и данных для проверки

Заголовок TCP

  • 16 битный порт источника > Номер порта источника
  • 16 битный порт назначения > Номер порта назначения
  • 32 битный последовательный номер > Последовательный номер генерируется источником и используется назначением, чтобы переупорядочить пакеты для создания исходного сообщения и отправить подтверждение источнику.
  • 32 битный номер подтверждения > Если установлен бит АСК поля "Управление", в данном поле содержит следующий ожидаемый последовательный номер.
  • 4 бита длина заголовка > Информация о начале пакета данных.
  • резерв > Резервируются для будущего использования.
  • 16 битная контрольная сумма > Контрольная сумма заголовка и данных; по ней определяется, был ли искажен пакет.
  • 16 битный указатель срочности > В этом поле целевое устройство получает информацию о срочности данных.
  • Параметры > Необязательные значения, которые указываются при необходимости.

Размер окна позволяет экономить трафик, рассмотрим когда его значение равно 1, тут на каждый отправленный ответ, отправитель ждет подтверждения, не совсем рационально.

При размере окна 3, отправитель отправляет уже по 3 кадра, и ждет от 4, который подразумевает, что все три кадра у него есть, +1.

Надеюсь у вас теперь есть представления об отличиях tcp udp протоколов.