Ist das TCP-Protokoll gut genug für Echtzeit-Multiplayer-Spiele?

57

Früher führten TCP-Verbindungen über DFÜ / ISDN / langsames Breitband zu ruckeligen, verzögerten Spielen, da ein einzelnes verworfenes Paket zu einer Resynchronisierung führte. Das bedeutete, dass viele Spieleentwickler ihre eigene Zuverlässigkeitsschicht über UDP implementieren mussten, oder UDP für Nachrichten verwendeten, die verworfen oder nicht ordnungsgemäß empfangen werden konnten, und eine parallele TCP-Verbindung für Informationen verwendeten, die zuverlässig sein mussten.

Kann ein Echtzeitspiel wie ein FPS eine gute Leistung über eine TCP-Verbindung erbringen, wenn der durchschnittliche Benutzer jetzt über schnellere Netzwerkverbindungen verfügt?

kevin42
quelle

Antworten:

36

Ich würde nein sagen. Die räumlichen Informationen von Spielobjekten müssen so schnell wie möglich sein, und dafür ist es besser, UDP zu verwenden, da die Zuverlässigkeit nicht zu 100% kritisch ist. Selbst bei modernen Verbindungen ist UDP noch so langsam, dass Sie einige spezielle Überlegungen zur Interpolation und dergleichen anstellen müssen. Selbst in Bezug auf die übertragene Datenmenge würde TCP einen erheblichen Mehraufwand verursachen.

TCP ist jedoch für Dinge, die nicht in Echtzeit ausgeführt werden, wie z. B. Mehrspielerverhandlungen, Chat-Nachrichten, Punkteaktualisierungen usw., durchaus akzeptabel.

Sean Edwards
quelle
7
Sean ist ziemlich am Geld. Wenn Sie zufällig ein Spiel in C # /. NET entwickeln (Sie wissen, dass Sie es möchten!), Hat sich die Lidgren-Netzwerkbibliothek ( code.google.com/p/lidgren-library-network ) als hübsch herausgestellt gute Wahl. Es bietet sogar geordnete, zuverlässige Nachrichtenübermittlung über UDP, falls Sie diese benötigen.
Mike Strobel
2
Es ist nicht ratsam, sowohl TCP als auch UDP zu mischen. Aufgrund der Art und Weise, wie TCP die Flusskontrolle durchführt, kann dies zu Paketverlust führen. (Quelle: isoc.org/INET97/proceedings/F3/F3_1.HTM )
Jason Kozak
4
Beachten Sie auch, dass Ihre Endbenutzer in einigen Fällen hinter ISPs sitzen, die UDP-Datenverkehr blockieren, über Router-Setups verfügen, die UDP-Datenverkehr verhindern, oder sich in einer Situation befinden, in der die Verwendung von UDP nicht optimal ist. In diesen Fällen ist es sehr praktisch, auf die TCP-Kommunikation zurückzugreifen, wenn Ihr Spiel dies unterstützen kann.
Charles Ellis
Ein weiterer Pluspunkt für UD ist, dass es natürlich paketorientiert ist. Sie müssen dies bei Bedarf in TCP emulieren (boilderplatecode). Leider werden die moderneren Protokolle nicht von Windows unterstützt (das ist zum Kotzen)
Quonux,
11

Da Flash UDP nicht unterstützt, können Sie sich in Multiplayer-Flash-Spielen ein Bild davon machen, was mit TCP / IP möglich ist und was nicht. Grundsätzlich können Sie Echtzeitspiele erstellen, sofern diese nicht auf blitzschnellen Reaktionszeiten beruhen. Einige Beispiele:

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

http://everybodyedits.com/

Wenn Sie die Option haben, UDP zu verwenden, sollten Sie dies wirklich tun, aber mit Flash erhalten Sie diese Option leider nicht.

Iain
quelle
8

Es hängt davon ab, ob.

Spiele wie World of Warcraft verwenden TCP für ihre Kommunikation, weil Sie damit viele Probleme umgehen. Dies kann zu einem höheren Ping führen, aber für viele Spiele ist dies akzeptabel. Sie müssen eine räumliche Interpolation durchführen, auch wenn Sie UDP als Protokoll verwenden.

Christopher
quelle
1
Es ist nicht nur Ping. Es gibt einen Grund, warum es in WoW keine Spieler-Spieler-Kollisionen gibt. Es wäre zu schwer, es gut zu machen. WoW kann TCP verwenden, da es nicht wichtig ist, wo Sie stehen. Das Zielen und Angreifen hängt nicht von der tatsächlichen Position des Monsters oder des gegnerischen Spielers ab. Wenn Sie sich für diese Dinge interessieren, wird TCP das Spielerlebnis beeinträchtigen.
Nuoji
6

Wenn Ihre Client / Server-Architektur sauber ist, spielt die Transportschicht (fast) keine Rolle.

TCP hat einige Nachteile, die jedoch leicht umgangen werden können.

Ja, TCP und ein Gehirn sind alles, was Sie brauchen.

Mit gängigen Netzwerk-Setups (Proxys, Firewalls usw.) ist UDP heutzutage für alle außer lokalen (sprich: LAN) Spielen so gut wie unbrauchbar.

Andreas
quelle
7
Wenn Sie abstimmen, hinterlassen Sie bitte einen Kommentar, warum. Wir verwenden TCP und hatten nie ein einziges Problem damit.
Andreas
3
Ich kann die Relevanz der gängigen Netzwerkeinstellungen darin nicht erkennen. Firewalls stören im Allgemeinen nur Hosting-Server, aber auch dann unabhängig vom Protokoll, wohingegen Proxys das Risiko von verzögerten oder verworfenen Paketen erhöhen und UDP weitaus nützlicher machen, als dies in einem lokalen Netzwerk der Fall wäre. Die Nachteile von UDP können weitgehend umgangen werden, indem Integritätsprüfungen selbst durchgeführt werden. Sie können jedoch keine Funktionen aus TCP herausnehmen, um es schneller zu machen.
Marcks Thomas
1
Sie müssen Nagles erwähnen . Ich vergesse immer, dass dies die Hauptursache dafür ist, dass TCP böse ist (Nagles puffert Pakete auf dem Client / Server, indem er sie im Grunde genommen aus Ihrem Spiel "zurückhält" und zusätzliche Verzögerungen einführt).
Bobobobo
Es gibt mehrere Gründe, warum Sie UDP anstelle von TCP verwenden sollten, wenn die Latenz ein Problem darstellt. Wenn Ihnen die Latenz egal ist und / oder Sie in der Lage sind, eine ausreichende Vorhersage auf der Clientseite zu treffen, kann TCP ausreichen. Bei Echtzeitspielen. Vergiss TCP.
Nuoji
6

Es ist durchaus akzeptabel, TCP anstelle von UDP zu verwenden - wenn Sie den Nagle-Algorithmus ausschalten .

Sobald Sie Nagle ausschalten, haben Sie den größten Teil der Geschwindigkeit von UDP und sind in der Lage, ein zuckendes Reaktionsspiel zu erstellen . In der Tat habe ich ein solches Spiel mit TCP in Flash gemacht:

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

Ich hoffe, das hilft!

wildbunny
quelle
Nicht betriebsbereite App unter Ihrem Link, Sir.
Ingenieur
Link komplett verrottet, Sir. Ich bekomme einen Apache Server Test.
Gustavo Maciel
4

Für FPS-Spiele verwenden wir immer UDP. Vor allem, wenn Sie einen Twitch-Shooter machen, bei dem es auf Pings ankommt.

Corv1nus
quelle
4

Das hängt von der Art des Spiels ab.

Einige Spiele wie RTS spielen viel besser über TCP und verwenden in der Regel die ganze Zeit TCP.

Das eigentliche Problem bei TCP ist, dass die Verbindung "blockiert", bis eine erneute Übertragung erfolgt, wenn Sie einen Paketverlust - auch nur eine geringe Menge - feststellen. Das Betriebssystem kann der Anwendung keine Daten liefern, die nicht in der richtigen Reihenfolge vorliegen (dies bricht die Garantien von TCP, aber TCP zeigt auch nicht die Rahmengrenzen der Anwendung an). Der Verbindungsabbau führt dazu, dass verspätete Daten später eintreffen. In einem (z. B.) FPS-Spiel sind veraltete Daten jedoch unbrauchbar.

Mit UDP kann die Anwendung auswählen, was sie mit verspäteten oder nicht ordnungsgemäßen Daten tut. Es kann (und für ein Spiel wie FPS normalerweise) alte Daten ignorieren und nur die neuesten verwenden. Ein gelegentlich verlorenes Paket verzögert nachfolgende Pakete überhaupt nicht. Wenn ein verzögertes Paket irgendwann eintrifft, kann es vom Spiel ignoriert werden.

MarkR
quelle
Beachten Sie, dass Ihre Implementierung den Aspekt des Verwerfens verzögerter Pakete behandeln muss, da UDP sie als empfangenes Datagramm behandelt.
Guvante
3

Akzeptieren Sie nicht einfach ein klares "Ja oder Nein, weil ich das gesagt habe", sondern geben Sie hier eine Antwort ein, da Sie sich möglicherweise dem Kampf gegen eine Reihe von Problemen mit UDP öffnen müssen, denen Sie sich eigentlich nicht stellen müssen.

Keine der anderen Antworten gibt den offensichtlichen Weg an, dies zu beweisen.

Nehmen Sie einige einfache Fakten

  • Ein IP-Header hat unabhängig vom verwendeten Protokoll eine Größe von 20 Byte.
  • UDP-Header sind 4 Bytes
  • TCP-Header sind 20 Byte

Jedes Mal, wenn Sie eine Nachricht von 1 Byte über die Leitung senden, haben Sie je nach Protokoll entweder 25 oder 41 Byte gesendet, vorausgesetzt, ein IP-Header wird ebenfalls benötigt.

Quellen:

Mein Rat

Nehmen Sie Ihre Situation an, in der Sie eine Client-Server-Interaktion benötigen, schätzen Sie die Anzahl der Clients und rechnen Sie dann anhand der Daten, die Sie tatsächlich zwischen den beiden Clients senden.

Ein Beispiel

Nehmen wir an, ich sende 10 Nachrichten mit jeweils 1 Byte pro Aktualisierung in meinem Spiel und aktualisiere ungefähr 60 fps. Daher muss ich 60 * 10 = 600 Bytes pro Sekunde der tatsächlichen Nachrichtendaten + die relevanten Header senden.

Je nach Spiel könnte ich das alles als eine einzelne Nachricht senden, sodass mein Overhead von der TCP-Schicht nur 40 Bytes beträgt (was effektiv über UDP 20 Bytes pro Sekunde kostet), ohne dass dieser Overhead potenzielle Kosten von 600 Bytes sind ( weil ich möglicherweise den gesamten Nachrichtenstrom erneut senden muss).

Wenn es jedoch von entscheidender Bedeutung ist, dass jede Nachricht in dem Moment, in dem sie versandbereit ist, für sich selbst gesendet wird, habe ich 600 Nachrichten (auch 600 Byte) + 40 * 600 = 24 KB TCP-Overhead oder ~ 14 KB UDP-Overhead pro Sekunde + 600 Byte Nachrichtendaten.

Wieder stellen wir die Fragen, wie wichtig diese Nachrichten sind, wie häufig sie sind und ob sie in irgendeiner Weise zusammengefasst werden können, um den Overhead zu reduzieren.

Dies basiert lediglich auf einer Reihe von Einzelbyte-Nachrichten. Normalerweise würden Sie etwas ganz anderes tun, ohne jedoch zu wissen, dass die gesendeten Rohdaten nur schwer zu beweisen sind, ob TCP besser zu Ihrer Situation passt als UDP.

Also wird es funktionieren?

Nun, wenn Sie ein typisches fps haben und die Position wichtig ist (um Betrug oder falsche Entscheidungen zu vermeiden), müssen Sie wissen, dass Ihr Netzwerk-Stream realisierbar ist, aber 32 Spieler streamen jeweils 24k + Nachrichtenbytes hin und her (also 768KB / s + messages) ... das entspricht einer 10-MBit / s-Breitbandleitung nur für einzelne Header, basierend auf dem Senden von mindestens 1 Nachricht pro Frame von jedem Client an alle anderen Clients über einen Server.

Sie werden Ihren Server und Ihren Client offensichtlich nicht so codieren, und die Nachrichten sind sehr wahrscheinlich viel größer und in den meisten Situationen etwas seltener als 1 Byte pro Frame. Daher ist es schwer zu sagen, ohne eine reale Welt zu sehen Beispiel "das sind die Daten, die ich senden muss".

Mein Fall

Ich habe in meinem Fall den Anruf getätigt, dass es ein vernünftiger Overhead ist, aber er basiert darauf, wie ich meine Nachrichtenströme erstelle, damit ich im Vergleich zu einigen Designs keinen großen Overhead habe.

TCP funktioniert einwandfrei und ich habe ein skalierbares MMO-Server- und Client-Framework, aber ich muss nie viele Daten oder viele kleine Pakete streamen, da ich meine Anrufe stapeln kann.

für andere: TCP funktioniert einfach nicht und sie können nur UDP verwenden, müssen aber akzeptieren, dass es ihnen keine Zusicherung darüber gibt, was sie erhalten (Bestell- / Ankunftsgarantie).

Andere Überlegungen

Viele schlecht codierte Spiele-Engines verarbeiten alles auf dem Haupt-Thread der CPU, so dass der CPU oft nur sehr wenig Zeit für die Verarbeitung des Netzwerk-Codes zur Verfügung steht. Eine anständige Implementierung sowohl des Dienstes als auch des Clients wäre völlig asynchron und möglicherweise Push- und Nachrichten stapelweise abrufen.

Es gibt einige gute Netzwerkbibliotheken, aber wie hier zu sehen ist, scheinen viele der Meinung zu sein, dass UDP "einfach besser" ist. Berücksichtigen Sie zuerst Ihre eigenen Bedürfnisse, und das ist möglicherweise nicht der Fall, und finden Sie eine Bibliothek, die dies nicht tut Berücksichtigen Sie, wie Sie es tun, und führen Sie möglicherweise zu einem schlecht codierten TCP-Setup im Vergleich zur UDP-Variante in derselben Bibliothek (ich sage nur, dass ich das gesehen habe, und Lasttests haben es bewiesen).

Erstellen Sie zunächst eine technische Basis für die Daten, die Sie senden möchten, und testen Sie sie. Führen Sie dann die Berechnungen durch, um sie zu skalieren. Testen Sie sie im ungünstigsten Fall, indem Sie sie in einer Cloud bereitstellen, und lassen Sie 50 Computer einen Testclient ausführen, um zu prüfen, ob sie damit umgehen können Ihr Limit von 32 Spielern pro Spiel (oder welche Limits Sie auch haben mögen).

Krieg
quelle
2

Ich denke nicht ... Spiele, bei denen die Datenübertragung sehr häufig ist (bei Mausbewegungen oder bei gedrückter Taste), sollten UDP verwenden. Es wird sogar im LAN verzögert, wenn TCP verwendet wird.

Shashwat
quelle