UDP gegen TCP im Multiplayer-Handyspiel

7

Ich arbeite an einem vernetzten Multiplayer-Spiel, zunächst für iOS.

Selbst mit TCP_NODELAY gibt es große Latenzschwankungen. Ich kann mir des Grundes nicht sicher sein, aber ich wäre nicht überrascht, wenn der Paketverlust aufgrund flockiger Verbindungen erneut auftreten würde.

Nachdem ich im Gegensatz zu TCP (mit dem ich viel Erfahrung habe) keine echte Serverarbeit mit UDP geleistet habe, frage ich mich, ob der Versuch einer UDP-basierten Architektur signifikante Vorteile bringt.

Client-Pakete bestehen normalerweise nur aus wenigen Bytes und werden nur selten gesendet, außer beim Verschieben, wenn der Player möglicherweise 2-8 Befehle / s ausgibt. Serverpakete sind etwas größer und werden meist als Antwort auf einen Clientbefehl gesendet.

Verbindungen müssen zuverlässig und bestellt sein.

ZUSÄTZLICHE INFORMATION

Sehr früh habe ich einige Erkundungstests mit TCP im Vergleich zu UDP durchgeführt. Ich würde Verbindungen herstellen Phone -> 3G -> External static IP of router -> Wifi -> Development computerund Phone -> Wifi -> Router -> Wifi -> Development computer.

Was ich verbessern wollte, war hauptsächlich die sehr ungleichmäßige Verzögerung, die man beim Bewegen auf der Karte mit einer nicht lokalen Verbindung erleben würde.

Natürlich kann das Starten von Animationen helfen, aber es gibt (seltene, aber gültige) Gründe, warum ein Verschiebungsbefehl abgelehnt werden kann, die der Client nicht vorhersagen kann. Darüber hinaus sind viele Daten vor dem Client verborgen, was wiederum nur sehr wenig Raum für prädiktive Antworten bietet.

Wie auch immer, meine Ergebnisse waren, dass UDP und TCP beim Senden von Daten fast die gleiche durchschnittliche Latenzzeit hatten.

Was ich nicht gesehen habe, war die tatsächliche Verbreitung - zum Beispiel die maximale TCP-Latenz angesichts des Paketverlusts. Ich hätte einen Paketwiederherstellungsmechanismus in UDP durchführen müssen, um herauszufinden, ob UDP es besser machen könnte.

Also noch einmal die Ergebnisse , die ich mit TCP heute sehen , ist , dass in der Regel funktioniert es gut, dann plötzlich eine Verlangsamung und ein Platzen der Bewegung wie alle anderen gepufferten Pakete sind mehr oder weniger zur gleichen Zeit ausgeführt.

Nuoji
quelle
TCP ist im Allgemeinen für Spiele zu langsam, da der Overhead nur die Leistung beeinträchtigt, um sicherzustellen, dass Sie das bekommen, was Sie wollen. UDP hingegen ist so viel schneller und manchmal können Sie es sich leisten, ein paar Pakete in einem Multiplayer-Spiel zu verlieren, solange Sie dies wieder wettmachen können.
OmniOwl
2
gafferongames.com/networking-for-game-programmers/udp-vs-tcp - Immer eine gute Lektüre für alles. Das heißt, wenn Sie es nicht ausgecheckt haben!
Luke San Antonio Bialecki
7
TCP wird heutzutage von einer großen Anzahl von Spielen verwendet. Können Sie überprüfen, ob TCP die Ursache für Ihre Latenz ist, anstatt nur zu raten? Gibt es einen guten Grund, warum Sie eine ganze Verbindung benötigen, um zuverlässig und geordnet zu sein, und nicht nur bestimmte Streams / Nachrichten? Tritt dies in einem Testemulator / einer Testumgebung oder in einer Bereitstellung auf? Kabelgebunden oder drahtlos? LAN oder Internet? Sie haben ein Problem, eine zufällige Vermutung der Grundursache und eine vage Frage zu "Was ist das Beste?"
Sean Middleditch
@ SeanMiddleditch fair genug, ich habe einige Details hinzugefügt. Ich weiß , wenn das TCP Verhalten die Ursache ist, aber ich bin ziemlich sicher , ich habe einige Paketverlust (leicht in meinem Setup zu bekommen), und schauen, wie TCP funktioniert und die Kosten für eine Hin- und Rück, ich konnte leicht sehen , wie die beobachtete Verhalten könnte entstehen. Ich bin nicht sicher, ob ein benutzerdefiniertes UDP-Schema funktionieren könnte, aber ich weiß auch nicht, ob es sich lohnt, es zu untersuchen. Ich nehme an, es gibt Fälle, in denen es manchmal möglich ist, unzuverlässige Transfers zuzulassen (z. B. geht der Spieler dreimal nach Norden -> es ist in Ordnung, nur zweimal nach Norden zu gehen).
Nuoji

Antworten:

7

Es stellt sich heraus, dass dies daran liegt, wie Energiesparen in Mobiltelefonen funktioniert.

Wenn Sie für mein iPhone alle 200 ms einen stetigen Strom von UDP-Pings senden, bleibt die Schnittstelle offen und ich erhalte eine RTT von 80-100 ms. Durch Verringern der Ping-Frequenz wird die RTT drastisch auf durchschnittlich etwa 400 ms erhöht. Eine weitere Reduzierung der Frequenz führt dazu, dass die RTT gelegentlich noch höher wird.

TCP ist etwas anders, da das Betriebssystem die offene Verbindung besser kennt. Was mir aufgefallen ist, ist, dass TCP bei schlechten Verbindungen (unabhängig davon, ob es sich um WLAN oder 3G handelt) aufgrund seines Verhaltens "Paketverlust = Ich verwende zu viel Bandbreite" stark leiden kann.

In meinem Fall ist es möglich, ein ziemlich einfaches "zuverlässiges UDP" zu erstellen, das TCP - für mein Spiel - überlegen ist, indem der Client alle 200 ms ein Paket sendet und wiederholt Pakete sendet, die nicht bestätigt wurden.

Dies funktioniert insbesondere ein bisschen wie der Q3-Code. Wenn Sie ein Paket mit der Sequenznummer n erhalten, können Sie alle Pakete n - 1 oder früher verwerfen, ohne Daten zu verlieren (da ein Paket mit der Sequenznummer n alle zuvor nicht gepackten Befehle enthält )

Wenn Paket n verloren geht, kommt in 200 ms immer noch ein Paket n + 1 mit diesen Daten an.

Dies kostet das gelegentliche unnötige erneute Senden (wenn eine Bestätigung mehr als 200 ms benötigt, um anzukommen), aber die Latenz ist auf maximal ("Netzwerkunterbrechungszeit" + Ping-Intervall) reduziert.

Dies würde nicht gut funktionieren, wenn die Pakete ziemlich groß wären, so dass ein erneutes Senden eines Pakets dazu führen würde, dass das nächste Paket fragmentiert wird. Es gibt auch viele andere implizite Annahmen, daher würde ich dies niemandem als General empfehlen Lösung .

Mein Punkt ist, dass UDP die Flexibilität ermöglicht, ein Schema zu entwickeln, das auf Ihr bestimmtes Spiel zugeschnitten werden kann. Wenn dies die Unannehmlichkeiten beim Entwerfen des UDP-Protokolls überwiegt, hängt dies von den Einzelheiten des Spiels ab.

Nuoji
quelle
1
Bei Verwendung von UDP bei einer schlechten Verbindung leidet der Player ebenfalls stark. Seine Eingaben werden zufällig auf den Server übertragen und seine Aktualisierungen des Spielstatus werden zufällig eingehen. Damit das Spiel auf UDP funktioniert, muss der Entwickler die Hälfte von TCP nur schlecht neu erfinden.
Zan Lynx
Es hängt alles von der Anwendung ab. UDP führt keine Magie aus, aber es ermöglicht Ihnen, spezifische Minderungsstrategien zu spielen, die mit TCP nicht möglich sind.
Nuoji
Das sind einige interessante Informationen über UDP auf iPhones (und wahrscheinlich anderen Handheld-Geräten). Haben Sie Links, über die ich mehr lesen kann?
John McDonald
2
@Zan Lynx, die Verwendung von TCP über eine schlechte Verbindung ist noch schlimmer als UDP. Mit UDP können Sie einen Algorithmus erstellen, um verworfene Pakete über Interpolation, Verzögerungen usw. zu verarbeiten (siehe Quell-Multiplayer-Netzwerk). TCP über eine schlechte Verbindung bedeutet, dass das gesamte Spiel wiederholt zum Stillstand kommt, während verlorene Pakete erneut gesendet werden, was bei einer schlechten Verbindung sehr häufig vorkommt. TCP eignet sich für solide Verbindungen mit genügend Bandbreite, um die Datenlast zu unterstützen (Beispiel: LAN, Breitband). UDP mit ein wenig zusätzlicher Arbeit wird immer bei schlechten Verbindungen ausgeführt. Dies wurde mit Doom / Quake und vielen anderen älteren Spielen gemacht.
Jyro117
1
@Zan Lynx: Es hat absolut eine Reihe von Versionen gedauert, bis ein gutes Netzwerkprotokoll ermittelt wurde. Ich wollte nur darauf hinweisen, dass die Verwendung von UDP keine schlechte Sache ist, am Ende wird es immer von vielen Faktoren abhängen, die mit dem Spiel / der Umgebung zusammenhängen.
Jyro117
-1

In den obigen Kommentaren und Antworten scheint es eine beträchtliche Menge an Fehlinformationen zu geben, einschließlich der Referenzierung von Papieren, die nicht mehr relevant sind.

Sie sollten sowohl UDP als auch TCP in Ihrem Spiel verwenden, und die Argumentation ist wirklich recht einfach:

Sie sollten TCP für die zuverlässige Übertragung zeitunempfindlicher Aktionen wie Basis-Heartbeat und anderer blockierender Transaktionen (wirklich HTTP) verwenden. Einige kurze Hinweise:

  1. Hüte dich vor Nagles Algorithmus , bei dem der Netzwerkstapel versucht, kleine TCP-Pakete zu puffern, um das Verhältnis von Daten zu IP-Overhead zu verringern. Normalerweise können Sie diese Funktionalität deaktivieren.
  2. Wenn eine Netzwerküberlastung auftritt, versucht TCP, die Verbindung zu verlangsamen, indem die Fenstergröße vorübergehend verringert und im Laufe der Zeit wieder auf den Normalwert erhöht wird. Dies wirkt sich nicht mehr auf die UDP-Übertragung aus.

UDP sollte für die zeitkritische Datenübertragung verwendet werden z. B. für die aktivsten Teile eines Online-Spiels (Bewegung usw.).

Sie können natürlich auch einfach UDP verwenden und Zuverlässigkeit aufbauen, um das Beste aus beiden Welten herauszuholen. Aber es kostet Sie Zeit und Komplexität und am Ende die besten Lösungen, die beste Vorhersage und Benutzerinteraktion, die für Netzwerkprobleme transparent sind.

S.Richmond
quelle
Ob es für TCP, UDP oder eine Mischung sinnvoll ist, hängt ganz davon ab, wie das Spiel funktioniert. Es ist nicht besser, eine Annahme darüber zu treffen, was man ohne Rücksicht auf die spezifischen Anforderungen verwenden sollte, als eine zufällige Vermutung anzustellen. Die Entwicklung einer "zuverlässigen" UDP-Lösung ist in Bezug auf die Komplexität nicht schlechter als die Erstellung einer soliden, skalierbaren Server-Client-Lösung mit TCP. Zum Beispiel ist die Vorhersage des Kunden in Ordnung, aber nicht immer in jedem einzelnen Spieltyp möglich.
Nuoji
Weitere Informationen zu "Sie sollten sowohl UDP als auch TCP verwenden" finden Sie unter "Warten? Warum kann ich nicht sowohl UDP als auch TCP verwenden?". Kapitel von gafferongames.com/networking-for-game-programmers/udp-vs-tcp
serg.nechaev