Имеет ли смысл использовать одновременно TCP и UDP?

10

После прочтения UDP еще лучше, чем TCP для игр с большим объемом данных в реальном времени? Мне интересно, имеет ли смысл использовать одновременно TCP и UDP, но для разных вещей:

  • TCP для отправки информации, которая отправляется нечасто, но должна быть гарантированно надежно доставлена.
    Такие как обновления счета, имя игрока или даже состояние включения / выключения света в игровом мире.

  • UDP для передачи информации, которая постоянно обновляется и может время от времени теряться, поскольку новая информация всегда в пути.
    Например, положение, вращение и т. Д.

Это разумная идея? Каковы возможные недостатки?
Есть ли лучшие способы справиться с этим?

gandalf3
источник
Обязательно прочтите остальные темы на этом сайте, касающиеся udp и tcp. Вы найдете несколько деталей, которые по существу касаются ваших вопросов. В качестве гипотезы: я подозреваю, что существуют гибридные протоколы по протоколу UDP, которые пытаются извлечь максимальную выгоду из обоих миров, то есть с более низкой задержкой, стратегией конкуренции, балансировкой нагрузки и гарантиями доставки. Как было предложено, ищите связанные вопросы по теме и сузьте свой вопрос до того, что, по вашему мнению, еще не было здесь рассмотрено.
Теодрон
@teodron Тебе не нужно подозревать. Как указано в моем ответе, это факт.
инженер

Ответы:

8

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

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

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

инженер
источник
1
Чтобы сделать ответ немного «более простым», не могли бы вы предоставить краткий (очень короткий) список опций / ссылок для транспортных библиотек на основе UDP? (возможно ENET, RakNet, zeroMQ, UDT?). Что касается моего комментария выше, я уверен, что я видел обсуждение этого где-то на этом сайте, но, возможно, стоит скопировать фрагмент этой информации.
Теодрон
1
@Arcane Engineer Что если сокеты UDP и TCP работают на разных портах?
KaareZ
@KaareZ Не должно иметь никакого значения вообще. Исследования, которые были проведены (см. Ссылку в редактировании), были бы недействительными, если бы это было простым делением на порты. В конце концов, порт - это просто программный порт. Это на самом деле не влияет на характеристики сети, к чему все сводится.
Инженер
То, что вы говорите, имеет смысл, но я не могу не задаться вопросом, применяется ли это по-прежнему там, где очень мало TCP-трафика. Если по TCP передаются только небольшие объемы информации, скажем, в среднем один или два раза каждые ~ 10 секунд, действительно ли это заметно повлияет на трафик UDP?
gandalf3
2
Бумага «TCP вызывает потерю пакетов UDP» не имеет даты. Последние упоминания датируются 1996 годом. С каких это пор бумага? Все еще верны выводы?
Андреас
4

Вот цитата Сэма Янсена из комментария на gafferongames.com :

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

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

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

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

Чтобы ответить на ваш вопрос:

Мне интересно, имеет ли смысл использовать одновременно TCP и UDP, но для разных целей [...]

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

  • TCP для отправки информации, которая отправляется нечасто, но должна быть гарантированно надежно доставлена. Такие как обновления счета, имя игрока или даже состояние включения / выключения света в игровом мире.

При использовании как TCP, так и UDP, вы всегда должны отдавать как можно больше по UDP и как можно меньше по TCP.

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

Возможно нет.

UDP отлично работает для этих случаев, и Quake 3 является хорошим примером того, как это сделать.

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

Pubby
источник
3

Это разумная идея?

  • да

Каковы возможные недостатки?

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

Есть ли лучшие способы справиться с этим?

  • Используйте существующую надежную библиотеку UDP. Двумя наиболее популярными являются: сеть Лидгрена (C #), RakNet (C ++). По опыту могу сказать, что Lidgren очень прост в использовании, быстр и надежен.
Shmoopy
источник
1

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

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

Одно из решений - открыть временное TCP-соединение только во время передачи данных и немедленно закрыть его. Это замедлит транзакции, открытие tcp-соединения - довольно «дорогой» процесс. Как всегда, это все о разработке надежной системы с самого начала, чтобы обеспечить большой рост.

user102337
источник