Достаточно ли хорош протокол TCP для многопользовательских игр в реальном времени?


57

В свое время TCP-соединения по dialup / ISDN / медленной широкополосной сети приводили к прерывистым, медленным играм, потому что один отброшенный пакет приводил к повторной синхронизации. Это означало, что многим разработчикам игр приходилось реализовывать свой собственный уровень надежности поверх UDP, или они использовали UDP для сообщений, которые могли быть отброшены или получены не по порядку, и использовали параллельное соединение TCP для получения информации, которая должна быть надежной.

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


Ответы:


36

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

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


7
Шон в значительной степени на деньги. Если, случайно, вы разрабатываете игру в C # / .NET (вы знаете, что хотите!), Я обнаружил, что Сетевая библиотека Лидгрена ( code.google.com/p/lidgren-library-network ) довольно симпатичная. хороший выбор. Он даже обеспечивает упорядоченный, надежный обмен сообщениями по UDP, если вам это нужно.
Майк Штробель

2
Неразумно смешивать как TCP, так и UDP; В результате того, как TCP выполняет управление потоком, он может вызвать потерю пакетов. (источник: isoc.org/INET97/proceedings/F3/F3_1.HTM )
Джейсон Козак

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

Еще одним плюсом для UD является то, что он естественно ориентирован на пакеты, вы должны эмулировать это в TCP, если это необходимо (boilderplatecode), к сожалению, более современные протоколы не поддерживаются окнами (это отстой)
Quonux,

11

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

http://www.xgenstudios.com/play/stickarena

http://everybodyedits.com/

Если у вас есть возможность использовать UDP, вы действительно должны, но с Flash вы, к сожалению, не получаете эту опцию.


8

По-разному.

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


1
Это не просто пинг. Есть причина, по которой в WoW нет столкновений между игроками. Это было бы слишком сложно сделать хорошо. WoW может использовать TCP, потому что то, где вы стоите, не имеет большого значения. Таргетинг и атака не зависят от реальной позиции монстра или вражеского игрока. Если вы заботитесь об этих вещах, то TCP ухудшит игровой процесс.
Нуоджи

6

Если ваша клиент-серверная архитектура чиста, транспортный уровень (почти) не имеет значения.

У TCP есть некоторые недостатки, но их легко обойти.

Так что да, TCP и мозг - это все, что вам нужно.

С распространенными сетевыми настройками (прокси, брандмауэры и т. Д.) Сегодня UDP практически бесполезен для всех, кроме локальных (читай: LAN) игр.


7
Если вы отрицаете, пожалуйста, оставьте комментарий, почему. Мы используем TCP и никогда не сталкивались с ним.
Андреас

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

1
Вы должны упомянуть Нагл . Я всегда забываю, что это коренная причина, по которой TCP является злом (Nagle буферизует пакеты на клиент-сервере, в основном «скрывая» их от вашей игры и вводя дополнительную задержку).
Бобобобо

Существует несколько причин, по которым вы должны использовать UDP вместо TCP, если проблема заключается в задержке. Если вас не волнует задержка и / или вы можете сделать достаточно предсказаний на стороне клиента, тогда TCP может быть достаточно. В случае игр в реальном времени. Забудь о ПТС.
Нуоджи

6

Вполне допустимо использовать TCP вместо UDP - если вы отключите алгоритм Nagle .

Как только вы выключите Nagle, у вас будет большая часть скорости UDP, и вы сможете в полной мере создать игру с быстрой реакцией . Действительно, я сделал такую ​​игру, используя TCP во Flash:

http://2dspacemmo.wildbunny.co.uk

Надеюсь, это поможет!


Неработающее приложение по вашей ссылке, сэр.
инженер

Ссылка полностью рухнула, сэр. Я получаю тест сервера Apache.
Густаво Масиэль

4

Для игр FPS мы всегда используем UDP. Особенно, если вы делаете шутер, где пинг имеет значение.


4

Это зависит от типа игры.

Некоторые игры, такие как RTS, играют намного лучше, чем TCP, и обычно используют TCP все время.

Реальная проблема с TCP состоит в том, что если вы получаете потерю пакета - даже небольшую сумму - тогда соединение "останавливается" до повторной передачи. Операционная система не может доставлять неупорядоченные данные в приложение (это нарушает гарантии TCP, но также и TCP не показывает границы фрейма приложения). Остановка соединения означает, что впоследствии поступают поздние данные. Но в (например) FPS-игре устаревшие данные бесполезны.

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


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

3

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

Ни в одном из других ответов здесь не указан очевидный способ доказать это.

Возьмите несколько простых фактов

  • IP-заголовок составляет 20 байтов, независимо от того, какой протокол вы используете.
  • Заголовки UDP - 4 байта
  • Заголовки TCP 20 байтов

Таким образом, каждый раз, когда вы отправляете сообщение длиной 1 байт по линии, вы фактически отправили 25 или 41 байт в зависимости от протокола, предполагая, что IP-заголовок также необходим.

источники:

Мой совет

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

Пример

Допустим, я отправляю 10 сообщений по 1 байту на каждое обновление в моей игре, и я обновляю около 60 кадров в секунду, поэтому мне нужно отправить 60 * 10 = 600 байтов в секунду фактических данных сообщения + соответствующие заголовки.

Теперь, в зависимости от игры, я мог бы отправить все это в виде одного сообщения, поэтому мои издержки на уровне TCP составляют всего 40 байтов (фактически стоимость по UDP составляет 20 байтов в секунду), при отсутствии таких издержек потенциальная стоимость составляет 600 байтов ( потому что мне, возможно, придется переслать весь поток сообщений).

Однако, если жизненно важно, чтобы каждое сообщение отправлялось само по себе в момент, когда оно будет готово к отправке, у меня есть 600 сообщений (также 600 байтов) + 40 * 600 = 24 Кбайт издержек TCP или ~ 14 Кб накладных расходов UDP в секунду + 600 байтов данных сообщения.

Опять же, мы задаем вопросы, насколько важны эти сообщения, как часто они и могут ли они быть каким-то образом объединены, чтобы уменьшить накладные расходы?

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

Так будет ли это работать?

Что ж, если у вас типичный fps, и позиция важна (чтобы избежать мошенничества или неправильных решений), вам нужно знать, что ваш сетевой поток является реальным, но каждый из 32 игроков передает это 24k + сообщение байтов назад и вперед (так 768 КБ / s + messages) ... это примерно 10 Мбит / с широкополосной линии только для отдельных заголовков, основанной на отправке по крайней мере 1 сообщения на кадр от каждого клиента всем другим клиентам через сервер.

Вы, очевидно, не будете кодировать свой сервер и клиент для такой работы, а размеры сообщений, скорее всего, будут намного больше и, вероятно, будут чуть менее частыми, чем 1 байт на кадр, в большинстве случаев, поэтому трудно сказать, не видя реального мира. Пример «это данные, которые мне нужно отправить».

Мое дело

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

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

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

Другие соображения

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

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

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


2

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.