Le protocole TCP est-il suffisant pour les jeux multijoueurs en temps réel?

57

De retour dans la journée, les connexions TCP par ligne commutée / RNIS / large bande lente entraînaient des jeux agités et décalés, car un seul paquet supprimé entraînait une resynchronisation. Cela signifiait que de nombreux développeurs de jeux devaient implémenter leur propre couche de fiabilité par-dessus UDP, ou ils utilisaient UDP pour les messages pouvant être supprimés ou reçus dans le désordre, et utilisaient une connexion TCP parallèle pour obtenir des informations fiables.

Étant donné que l'utilisateur moyen dispose maintenant de connexions réseau plus rapides, un jeu en temps réel tel qu'un FPS peut-il offrir de bonnes performances avec une connexion TCP?

kevin42
la source

Réponses:

36

Je dirais non. Les informations spatiales des objets de jeu doivent être aussi rapides que possible, et pour cela, il est préférable d'utiliser UDP, car la fiabilité n'est pas à 100% fondamentale. Même sur les connexions modernes, UDP est encore suffisamment lent pour que vous deviez prendre en compte des considérations spéciales pour l’interpolation, etc. Même en termes de quantité de données transférées, TCP augmenterait considérablement les coûts.

Cependant, TCP est parfaitement acceptable pour des choses qui ne sont pas en temps réel, telles que la négociation multijoueur, les messages de discussion en ligne, les mises à jour des scores, etc.

Sean Edwards
la source
7
Sean est à peu près sur l'argent. Si, par hasard, vous développez un jeu en C # / .NET (vous savez que vous voulez!), J'ai trouvé la bibliothèque réseau de Lidgren ( code.google.com/p/lidgren-library-network ) très jolie. bon choix. Il fournit même une messagerie ordonnée et fiable sur UDP, si vous en avez besoin.
Mike Strobel
2
Il est déconseillé de mélanger TCP et UDP; En raison de la manière dont TCP effectue le contrôle de flux, il peut induire une perte de paquets. (source: isoc.org/INET97/proceedings/F3/F3_1.HTM )
Jason Kozak
4
Il est également important de garder à l'esprit que, dans certains cas, vos utilisateurs finaux resteront derrière des FAI qui bloquent le trafic UDP, ont des configurations de routeur empêchant le trafic UDP ou sont dans une situation où l'utilisation d'UDP est loin d'être idéale. Dans ces cas, si votre jeu peut le supporter, il est très pratique de pouvoir utiliser la communication TCP.
Charles Ellis
Un autre point + pour UD est que son orientation naturelle sur les paquets, vous devez émuler ceci dans TCP si besoin est (boilderplatecode), malheureusement, les protocoles les plus modernes ne sont pas supportés par windows (ça craint)
Quonux
11

Comme Flash ne prend pas en charge le protocole UDP, vous pouvez vous faire une bonne idée de ce qui est possible avec TCP / IP et de ce qui ne l’est pas. Fondamentalement, vous pouvez créer des jeux en temps réel, à condition qu'ils ne reposent pas sur des temps de réponse extrêmement rapides. Quelques exemples:

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

http://everybodyedits.com/

Si vous avez la possibilité d’utiliser UDP, vous devriez vraiment, mais avec Flash, malheureusement, vous n’obtenez pas cette option.

Iain
la source
8

Ça dépend.

Des jeux comme World of Warcraft utilisent TCP pour leur communication, car vous évitez beaucoup de problèmes en l'utilisant. En conséquence, il est possible que le ping soit plus élevé, mais pour de nombreux jeux, cela est acceptable. Vous devez effectuer une interpolation spatiale même lorsque vous utilisez UDP comme protocole.

Christopher
la source
1
Ce n'est pas juste un ping. Il y a une raison pour laquelle il n'y a pas de collision entre joueurs dans WoW. Ce serait trop difficile de bien faire. WoW peut utiliser le protocole TCP, car peu importe où vous vous trouvez. Le ciblage et l'attaque ne dépendent pas de la position réelle du monstre ou du joueur ennemi. Si vous vous souciez de ces choses, alors TCP nuira à l'expérience de jeu.
Nuoji
6

Si votre architecture client / serveur est propre, la couche de transport (presque) importe peu.

TCP présente certains inconvénients, mais ceux-ci sont faciles à contourner.

Alors oui, TCP et un cerveau sont tout ce dont vous avez besoin.

Avec les configurations réseau communes (proxies, pare-feu, etc.), UDP est aujourd'hui pratiquement inutile pour tous les jeux sauf les jeux locaux (lire: LAN).

Andreas
la source
7
Si vous votez vers le bas, s'il vous plaît laissez un commentaire pourquoi. Nous utilisons TCP et n’avons jamais eu un seul problème.
Andreas
3
Je ne vois pas la pertinence des configurations réseau communes dans ce domaine. Les pare-feu n'interfèrent généralement que sur les serveurs d'hébergement, mais quel que soit le protocole utilisé, alors que les mandataires augmentent en fait le risque de paquets retardés ou perdus, rendant UDP bien plus utile qu'il ne le serait sur un réseau local. Les inconvénients d’UDP peuvent être largement contournés en effectuant vous-même des vérifications d’intégrité, mais vous ne pouvez pas utiliser les fonctionnalités de TCP pour accélérer les choses.
Marcks Thomas
1
Vous devez mentionner Nagles . J'oublie toujours que c'est la raison fondamentale pour laquelle TCP est néfaste (les paquets de tampons de Nagle chez le client / serveur, en les "retenant" de votre jeu et en introduisant un délai supplémentaire).
Bobobobo
Il existe plusieurs raisons pour lesquelles vous devez utiliser UDP au lieu de TCP si la latence est un problème. Si vous ne vous souciez pas de la latence et / ou que vous êtes capable de faire suffisamment de prédiction côté client, alors TCP peut être suffisant. Dans le cas des jeux en temps réel. Oubliez TCP.
Nuoji
6

Son parfaitement acceptable d'utiliser TCP au lieu de UDP - si vous désactivez l' algorithme de Nagle .

Une fois que vous désactivez Nagle, vous avez presque toute la vitesse d’UDP et serez pleinement en mesure de faire un jeu de réaction en secousse . En effet, j'ai créé un tel jeu en utilisant TCP en Flash:

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

J'espère que ça t'as aidé!

lapin sauvage
la source
Application non opérationnelle sur votre lien, monsieur.
Ingénieur
Link a complètement tourné, monsieur. Je reçois un test de serveur Apache.
Gustavo Maciel
4

Pour les jeux FPS, nous utilisons toujours UDP. Surtout si vous faites un tireur de contraction où les pings importent.

Corv1nus
la source
4

Cela dépend du genre de jeu.

Certains jeux, tels que RTS, jouent beaucoup mieux avec TCP et utilisent généralement TCP tout le temps.

Le vrai problème avec TCP est que si vous perdez un paquet - même un petit montant -, la connexion "s'arrête" jusqu'à ce que la retransmission se produise. Le système d'exploitation ne peut pas fournir de données dans le désordre à l'application (cela rompt les garanties de TCP, mais TCP ne montre pas non plus les limites du cadre de l'application). Le blocage de la connexion signifie que des données tardives arrivent par la suite. Mais dans un (par exemple) jeu FPS, des données obsolètes sont inutiles.

Avec UDP, l’application peut choisir ce qu’elle fait avec les données en retard ou hors service. Il peut (et généralement pour un jeu tel que FPS) ignorer les anciennes données et simplement prendre les dernières. Un paquet perdu occasionnellement ne retarde pas du tout les paquets suivants. Si un paquet retardé arrive finalement, il peut être ignoré par le jeu.

MarkR
la source
Notez que votre implémentation devra gérer l'aspect de la suppression des paquets retardés, car UDP le traitera comme un datagramme reçu.
Guvante
3

N'acceptez pas simplement une réponse "oui ou non parce que je l'ai dit", car vous vous exposez peut-être à devoir vous attaquer à un tas de problèmes avec UDP auxquels vous n'avez pas à faire face.

Aucune des autres réponses ici n'indique le moyen évident de le prouver.

Prenons quelques faits simples

  • Un en-tête IP comporte 20 octets, quel que soit le protocole utilisé.
  • Les en-têtes UDP sont 4 octets
  • Les en-têtes TCP ont 20 octets.

Ainsi, chaque fois que vous envoyez un message d'un octet sur la ligne, vous avez effectivement envoyé 25 ou 41 octets, en fonction du protocole, en supposant qu'un en-tête IP est également nécessaire.

sources:

Mon conseil

Prenez votre situation où vous avez besoin d’une interaction client-serveur, estimez le nombre de clients, puis faites le calcul en fonction des données que vous envoyez réellement entre les 2.

Un exemple

Disons que j'envoie 10 messages de 1 octet par mise à jour dans mon jeu et que je mets à jour environ 60 ips; je dois donc envoyer 60 * 10 = 600 octets par seconde de données de message réelles + les en-têtes correspondants.

Maintenant, en fonction du jeu, je peux envoyer tout cela en un seul message, de sorte que la surcharge de la couche TCP ne représente que 40 octets (soit un coût sur UDP de 20 octets par seconde). Ne pas avoir cette surcharge représente un coût potentiel de 600 octets ( parce que je pourrais avoir à renvoyer le flux de messages entier).

S'il est toutefois extrêmement important que chaque message soit envoyé seul au moment où il est prêt à être envoyé, j'ai 600 messages (également 600 octets) + 40 * 600 = 24k de temps système TCP ou ~ 14k de temps système UDP par seconde + 600 octets de données de message.

Encore une fois, nous posons les questions suivantes: quelle importance ont ces messages, quelle est leur fréquence et peuvent-ils être regroupés d’une manière ou d’une autre afin de réduire les frais généraux?

Ceci est basé sur une série de messages mono-octet. En général, vous feriez quelque chose de très différent, mais vous ne sauriez pas si les données brutes envoyées sont difficiles à prouver si le protocole TCP convient mieux à votre situation que le protocole UDP.

Alors, ça va marcher?

Eh bien, si vous avez un fps typique et que la position est importante (pour éviter les tricheries ou des décisions incorrectes), vous devez savoir que votre flux réseau est réalisable, mais 32 joueurs envoient chacun en continu plus de 24k octets de message (donc 768 Ko / s + messages) ... il s’agit d’une ligne à large bande de 10 Mo / s, réservée aux en-têtes individuels, qui consiste à envoyer au moins un message par image de chaque client à tous les autres clients via un serveur.

De toute évidence, vous n'allez pas coder votre serveur et votre client pour qu'ils fonctionnent de cette manière et la taille des messages risque d'être beaucoup plus grande et probablement moins fréquente qu'un octet par image dans la plupart des situations, il est donc difficile de dire sans voir le monde réel. "Ce sont les données que je dois envoyer" exemple.

Mon cas

Dans mon cas, je me suis dit que les frais généraux étaient raisonnables, mais que cela dépend de la manière dont je construis mes flux de messages afin d'éviter des frais généraux énormes par rapport à certains modèles.

Le protocole TCP fonctionne bien et je dispose d’un serveur MMO évolutif et d’une infrastructure client, mais je n’ai pas besoin de diffuser beaucoup de données en continu ni de petits paquets car je peux traiter mes appels en lots.

pour les autres: TCP ne fera tout simplement pas l'affaire, et ils peuvent uniquement utiliser UDP, mais doivent accepter le fait que cela ne leur donnera aucune garantie quant à ce qu'ils obtiennent (garantie de commande / arrivée).

Autres considérations

De nombreux moteurs de jeu mal codés gèrent tout ce qui est sur le thread principal du cpu, de sorte que le cpu ne dispose souvent que de très peu de temps pour gérer le code réseau, une implémentation décente du serveur et du client serait entièrement asynchrone et éventuellement tirer des messages par lots.

Il existe de bonnes bibliothèques de réseautage, mais comme on peut le voir ici, beaucoup semblent être d’avis que UDP est "tout simplement meilleur", il faut bien prendre en compte vos propres besoins en premier et ce n’est peut-être pas le cas, et trouver une bibliothèque qui ne fonctionne pas En tenant compte de ce que vous faites, vous risquez de créer une configuration TCP mal codée par rapport à la variante UDP de la même bibliothèque (je dis simplement que j’ai vu cela et que les tests de charge l’ont prouvé).

Construisez d'abord une base technique des données que vous voulez envoyer et testez-la, puis faites le calcul pour la faire évoluer. Dans le cas le plus défavorable, testez-la en la déployant sur un cloud et demandez à 50 ordinateurs d'exécuter un client de test pour voir s'il peut gérer. votre limite de 32 joueurs par match (ou quelle que soit votre limite).

Guerre
la source
2

Je ne pense pas… Les jeux dans lesquels le transfert de données est très fréquent (en déplaçant la souris ou en appuyant sur une touche du bas) devraient utiliser le format UDP. Il y aura du retard même sur le LAN si TCP est utilisé.

Shashwat
la source