Ist UDP für datenintensive Echtzeitspiele immer noch besser als TCP?

71

Ich weiß, dass UDP normalerweise für Echtzeit-Multiplayer-Spiele mit hoher Datennutzung empfohlen wird.

Die meisten Artikel sind mehrere Jahre alt, und da ~ 80% aller im Internet übertragenen Daten TCP sind, muss für TCP eine Menge Optimierung durchgeführt worden sein.

Das wundert mich: Ist UDP in Bezug auf Geschwindigkeit und Latenz immer noch überlegen? Könnten die jüngsten TCP-Optimierungen dazu geführt haben, dass TCP eine bessere Leistung erzielt als UDP?

KaareZ
quelle
25
Bei UDP gibt es keine Garantie dafür, dass Ihre Pakete empfangen oder sogar bestellt werden. Dies allein macht UDP schneller als TCP.
Nathan
4
@KaareZ was meinst du schneller umzusetzen?
Nathan
2
@nathan Dass es einfacher ist, Ihre Anwendung mit TCP als mit UDP zu entwickeln. Ich möchte wissen, ob alle TCP-Optimierungen TCP in Bezug auf die Leistung zu einer besseren Option gemacht haben.
KaareZ
3
@ KaareZ Ich bin kein Experte, aber lassen Sie uns darüber nachdenken. Wie könnte TCP leistungsfähiger und dennoch ein zuverlässiges Protokoll sein? Du kannst nicht alles haben. TCP ist auf Zuverlässigkeit ausgelegt. Die eigentliche Frage ist, warum Sie TCP in Ihrem Spiel verwenden möchten?
Nathan
7
UDP ist genau dann besser als TCP, wenn Sie in der Lage sind (= erfahrene Netzwerkprogrammierer auf niedriger Ebene), genau die TCP-Funktionen, die Sie benötigen, effektiv neu zu implementieren. Löschen der unnötigen TCP-Funktionen für die Leistung.
Wondra

Antworten:

119

Nein, UDP ist in Bezug auf die Leistungslatenz immer noch überlegen und wird aufgrund der Philosophie der beiden Protokolle immer schneller sein - vorausgesetzt, Ihre Kommunikationsdaten wurden mit Blick auf UDP oder eine andere verlustbehaftete Kommunikation entwickelt.

TCP erstellt eine Abstraktion, in der alle Netzwerkpakete in der genauen Reihenfolge ankommen, in der sie gesendet wurden. Um eine solche Abstraktion auf einem verlustbehafteten Kanal zu implementieren, müssen Neuübertragungen und Zeitüberschreitungen implementiert werden, die Zeit verbrauchen. Wenn Sie zwei Updates über TCP senden und ein Paket des ersten Updates verloren geht, wird das zweite Update erst angezeigt, wenn:

  1. Der Verlust des ersten Updates wird erkannt.
  2. Eine erneute Übertragung des ersten Updates wird angefordert.
  3. Die erneute Übertragung ist eingetroffen und wurde verarbeitet.

Es spielt keine Rolle, wie schnell dies in TCP geschieht, denn bei UDP verwerfen Sie einfach das erste Update und verwenden das zweite, aktuellere. Im Gegensatz zu TCP garantiert UDP nicht, dass alle Pakete ankommen, und es garantiert nicht, dass sie in der richtigen Reihenfolge ankommen.

Dazu müssen Sie die richtigen Daten senden und Ihre Kommunikation so gestalten, dass ein Datenverlust akzeptabel ist.

Wenn Sie Daten haben, bei denen jedes Paket ankommen muss und die Pakete von Ihrem Spiel in der Reihenfolge verarbeitet werden müssen, in der sie gesendet wurden, ist UDP nicht schneller. In diesem Fall ist die Verwendung von UDP wahrscheinlich langsamer, da Sie TCP rekonstruieren und mithilfe von UDP implementieren. In diesem Fall können Sie auch TCP verwenden.

BEARBEITEN - Hinzufügen einiger zusätzlicher Informationen, um einige der Kommentare aufzunehmen / zu adressieren:

Normalerweise ist die Paketverlustrate bei Ethernet sehr niedrig, aber sie wird viel höher, wenn WiFi beteiligt ist oder wenn der Benutzer einen Upload / Download ausführt. Nehmen wir an, wir haben einen vollkommen gleichmäßigen Paketverlust von 0,01% (einfache Fahrt, keine Hin- und Rückfahrt). Bei einem Ego-Shooter sollten Kunden Aktualisierungen senden, wenn etwas passiert, z. B. wenn der Mauszeiger den Spieler dreht, was ungefähr 20 Mal pro Sekunde geschieht. Sie könnten auch Aktualisierungen pro Frame oder in einem festen Intervall senden, dh 60-120 Aktualisierungen pro Sekunde. Da diese Aktualisierungen zu unterschiedlichen Zeiten gesendet werden, sollten / werden sie in einem Paket pro Aktualisierung gesendet. In einem 16-Spieler-Spiel senden alle 16 Spieler diese 20-120 Pakete pro Sekunde an den Server, was insgesamt 320-1920 Pakete pro Sekunde ergibt. Bei unserer Paketverlustrate von 0,01% gehen wir davon aus, dass alle 5,2-31,25 Sekunden ein Paket verloren geht.

Für jedes Paket, das wir nach dem verlorenen Paket erhalten, senden wir ein DupAck, und nach dem dritten DupAck sendet der Absender das verlorene Paket erneut . Die Zeit, die TCP benötigt, um die erneute Übertragung einzuleiten, beträgt 3 Pakete zuzüglich der Zeit, die das letzte DupAck benötigt, um beim Absender anzukommen. Dann müssen wir warten, bis die erneute Übertragung eintrifft, sodass wir insgesamt 3 Pakete + 1 Roundtrip-Latenz warten. Die Roundtrip-Latenz beträgt in einem lokalen Netzwerk in der Regel 0-1 ms und im Internet 50-200 ms. 3 Pakete treffen normalerweise in 25 ms ein, wenn wir 120 Pakete pro Sekunde senden, und in 150 ms, wenn wir 20 Pakete pro Sekunde senden.

Im Gegensatz dazu erholen wir uns mit UDP von einem verlorenen Paket, sobald wir das nächste Paket erhalten, und verlieren 8,3 ms, wenn wir 120 Pakete pro Sekunde senden, und 50 ms, wenn wir 20 Pakete pro Sekunde senden.

Mit TCP werden die Dinge unübersichtlicher, wenn wir auch Nagle berücksichtigen müssen (wenn der Entwickler das Deaktivieren der Sende-Koaleszenz vergisst oder verzögertes ACK nicht deaktivieren kann ), die Vermeidung von Netzwerkstaus oder wenn der Paketverlust so schlimm ist, dass wir mehrere berücksichtigen müssen Paketverluste (einschließlich verlorener Ack und DupAck). Mit UDP können wir schnelleren Code schreiben, weil es uns einfach egal ist, wie TCP ein guter Netzwerkbürger zu sein.

Peter
quelle
Hinweis: UDP kann ein lokales Netzwerk übertragen (möglicher Vorteil), und da Vista die Ausführung von Server / Broadcast auf UDP durch den Administrator erfordert (Nachteil) (UAC / Firewall informieren den Benutzer in der Regel nicht über erforderliche Aktionen).
PTwr
7
"Wenn Sie 2 Updates über TCP senden und ein Paket des ersten Updates verloren geht" Stimmt, aber wie stehen die Chancen dafür? Laut Pingman : "
Mucaho
30
@Peter, du vergisst, dass in TCP jedes verworfene Paket jedes nachfolgende Paket blockiert . Bei einem Ping von 100 ms kann es leicht 300 bis 500 ms dauern, bis das Paket erneut gesendet und empfangen wird. Das sind also 6 bis 10 Pakete, die alle 33 Sekunden blockiert werden. Das wird sich in einem bebenartigen FPS definitiv bemerkbar machen.
BlueRaja - Danny Pflughoeft
12
Bei vielen TCP-Implementierungen dauert das erste Timeout nach einer fehlenden Bestätigung eine volle Sekunde. Das ist eine lange Zeit. Bei kleinen Paketen kann UDP eine oder zwei verpasste Übertragungen problemlos überbrücken, indem jedes Paket Daten aus den letzten beiden Aktualisierungen enthält, sodass die Anwendung die erforderlichen Daten erhält, bevor der Absender oder Empfänger erkennt, dass das erste Paket verloren gegangen ist.
Supercat
23
Bei einem Spiel wie Quake ist es irrelevant, das erste Paket zu verlieren. In weitaus weniger als der Zeit, die Sie benötigen würden, um den Verlust zu erkennen und das erste Paket erneut zu übertragen, hätten Sie bereits ein zweites Paket übertragen müssen, wodurch das erste sowieso veraltet wäre. Dies ist der gleiche Grund, warum viele Sprach- und Videoanwendungen in Echtzeit auch UDP verwenden. Wenn ein Paket verworfen wird, verlieren Sie lieber nur 0,02 Sekunden an Audio, als den gesamten Stream um eine volle Sekunde oder mehr zu verzögern. Das gleiche gilt im allgemeinen mit Echtzeit - Spiele, wie Sie wissen möchten , wo ein Objekt ist jetzt , nicht mehr als 1,5 Sekunden.
Reirab
19

Wir sind uns einig, dass sowohl TCP als auch UDP Protokolle sind, die auf IP aufbauen , nicht wahr? IP gibt an, wie Nachrichten über das Internet zugestellt werden. Dabei geht es jedoch nicht um die Nachrichtenstruktur und das Nachrichtenformat. Hier kommen TCP- und UDP-Protokolle. Sie verwenden IP-Eigenschaften, lassen den Programmierer sich jedoch auf den Nachrichtenaustausch konzentrieren, ohne sich um die unteren Schichten der Netzkommunikation zu kümmern. Und das ist großartig, denn der direkte Umgang mit analogen Signalen in Drähten wäre ziemlich schmerzhaft.

  • TCP bietet eine Reihe von Funktionen zum Senden und Empfangen von Nachrichten. Es teilt unsere Daten in kleine Pakete für uns auf und sendet sie über das Netzwerk. Wir werden lediglich gebeten, einen Port für den Net Socket und die eigentliche Nachricht zu verwenden, die wir senden möchten. Es ist auch zuverlässig, dh, wenn einige Pakete im Netzwerk verloren gehen, werden sie erkannt und erneut gesendet, wobei darauf geachtet wird, dass sie in der Reihenfolge gesendet werden, in der sie eigentlich ankommen sollten.

  • Auf der anderen Seite ist UDP ein Protokoll, das sich an der Benutzersteuerung orientiert. Wenn wir UDP zum Senden unserer Datagramme verwenden , können wir nicht sicher sein, ob das Datagramm jemals am Ziel ankommt oder nicht (und wir meinen hier mathematische Gewissheit: Wenn wir ein Paket senden, wird es wahrscheinlich ankommen, aber wir können nicht sicher sein, ob 100%). Wenn ein Paket verloren geht, wird es weder erkannt noch erneut gesendet.

An diesem Punkt scheint TCP die ideale Lösung für alle unsere Probleme zu sein. Es ist zuverlässig, schnell und löst die Verbindungslatenz für uns, indem es festhält, welche Pakete angekommen sind und welche Pakete noch gesendet werden müssen.

ABER , schau dahinter. Der einzige Vorteil von UDP ist die Geschwindigkeit, und genau das wollen wir wirklich. Ein UDP-Paket wird nur ohne bestimmte Steuerelemente erstellt, geprüft und gesendet, da das UDP-Protokoll so funktioniert. Ein TCP-Paket muss erstellt, beschriftet und geprüft werden, und wenn es ankommt, wird ein ACK zurückgesendet, um dem Absender mitzuteilen, dass "Paket x ist da, mach weiter" , und wenn dieses Signal nicht gesendet wird, bedeutet dies, dass ein solches Paket x gesendet werden muss nochmal.

Ich weiß, dass UDP normalerweise für Echtzeit-Multiplayer-Spiele mit hoher Datennutzung empfohlen wird.

Ja aber nicht nur UDP wird TCP vor allem deshalb vorgezogen, weil es aufgrund seiner hohen Geschwindigkeit für das Senden und Verwalten hoher Datenmengen geeignet ist. Dies ist der Fall, wenn ein solches Videospiel im deterministischen Gleichschritt ausgeführt wird (was auf dem Server geschieht, wird auf jedem Client unabhängig von der Netzwerklatenz identisch repliziert), ein Aktualisierungspaket verloren geht und niemals an sein Ziel gelangt. TCP würde ein solches Paket erneut senden, und die folgenden Pakete werden verworfen, weil sie nicht in der richtigen Reihenfolge ankommen, und werden dann nach dem verlorenen erneut gesendet. UDP ist in diesem Szenario viel toleranter: Dieses Paket ist ihm egal, da neuere Updates kommen. Das verlorene Update wird nicht gerendert, stattdessen wird die Spielphysik nach der verwendeten Integrationsmethode interpoliert und das letzte Update empfangen.

TCP verursacht Jittering, wenn die Latenz hoch genug ist, UDP nicht:

<video style="min-width: 100% height: auto" autoplay="" preload="auto" loop="true"><source src="https://gafferongames.com/videos/deterministic_lockstep_tcp_250ms_5pc.mp4" type="video/mp4"><source src="http://173.255.195.190/cubes_deterministic_lockstep_tcp_250ms_5pc.webm" type="video/webm">Your browser does not support the video tag.</video>

Ich frage mich daher, ob UDP in Bezug auf Geschwindigkeit und Latenz immer noch überlegen ist.

Nun ja, es ist und wird für eine lange Zeit. Weitere Informationen zu TCP und UDP finden Sie hier .

liggiorgio
quelle
8
TCP verwendet Ströme von Bytes anstelle von Datagrammen. UDP verwendet Datagramme. Gute TCP-Implementierungen halten die Pakete, die ankommen, in der falschen Reihenfolge, aber der Anwendung kann kein Paketinhalt zur Verfügung gestellt werden, es sei denn, oder bis alle vorhergehenden Pakete empfangen wurden. Wenn also ein Paket verloren geht, muss der Absender möglicherweise nicht alles, was auf das verlorene Paket folgte, erneut senden, aber die empfangende Anwendung würde erst dann etwas sehen, wenn das Paket erneut gesendet wird (woraufhin die Anwendung den Inhalt sofort sehen würde Paket und die danach).
Supercat
@supercat Leider kann TCP dem Absender nicht genau mitteilen, welche Pakete er empfangen hat und welche nicht. Es gibt nur einen Mechanismus für "Ich habe alle Bytes bis zur x-Sequenznummer erhalten." Wenn der Absender bereits empfangene Pakete erneut überträgt, werden die Kopien einfach ignoriert.
Reirab
@reirab: Ich dachte, es gibt einige moderne Erweiterungen, die dieses Feature enthalten, obwohl ich auch ohne dieses Feature denke, dass eine Implementierung, die Daten bis zu Byte 1.050.000 gesendet, aber nur Bestätigungen für Daten bis zu 1.000.000 erhalten hat, nach einer Sekunde ohne Gehör erhalten würde Wenn Sie mehr als 1.000.000 bestätigen möchten, senden Sie zunächst einen Datenblock von 1.000.000 bis 1.000.500, und warten Sie dann auf eine Antwort. Wenn es eine Bestätigung für Daten bis zu 1.000.500 erhält, kann es weitere Daten erneut übertragen. Wenn es eine Bestätigung für Daten bis zu 1.050.000 erhält, kann es die erneuten Übertragungen überspringen.
Supercat
1
@Giorgio IP gibt keinerlei Informationen zu analogen Signalen an. Dies geschieht auf der physischen Ebene. IP arbeitet zwei Schichten darüber auf der Netzwerkschicht. IP ist es egal, ob die Bits über Glasfaser, eine Satellitenverbindung oder ein 14,4-Kbit / s-DFÜ-Modem übertragen werden. UDP und TCP sind eine Schicht von IP auf der Transportschicht. Wie Supercat sagt, stellt TCP der Anwendung auch eine Stream-Schnittstelle zur Verfügung, keine Datagramm-Schnittstelle wie UDP.
Reirab
@supercat Hmm ... Sie haben vielleicht Recht mit modernen Erweiterungen, obwohl dies sicherlich nicht Teil des ursprünglichen TCP-Standards ist. Ein ACK hat nur eine laufende Nummer. Ich würde annehmen, dass eine TCP-Implementierung normalerweise das gesamte Sendefenster erneut überträgt, wenn ein Paket verworfen wird, anstatt auf jedes Paket eine gesamte RTT zu warten. Dies würde zu einer enormen Latenz führen, wenn mehrere aufeinanderfolgende Pakete mit sehr geringem Gewinn verloren gehen würden.
Reirab
9

TCP <- Transmission Control - Protokoll. Es ist gemacht, um die Übertragung zu steuern .

TCP wurde geschaffen, um ein guter und diplomatischer Netzwerkbürger zu sein. Es konzentriert sich darauf, das Networking zu einer guten Erfahrung für alle zu machen, und verringert bereitwillig den Durchsatz, um dies zu erreichen. Es passt sich der Umgebung an, indem es die Latenz erhöht . Gründe sind zum Beispiel:

  • Der Empfänger erkennt ein fehlendes Paket und fordert den Absender auf, langsamer zu arbeiten (die Rate für eine Weile zu halbieren).
  • Der Empfänger erkennt eine falsche eingehende Paketreihenfolge (möglicherweise wurden unterschiedliche Netzwerkpfade verwendet), fordert den Absender auf, langsamer zu arbeiten - und der Empfänger akzeptiert übrigens keine weiteren Pakete, bis das fehlende Paket eingeht.
  • Der Absender erkennt eine Überlastung des Netzwerks (z. B. langsame Roundtrip-Zeit) und erhöht die Latenz.
  • Der Empfänger kann nicht mit der Geschwindigkeit mithalten (der Eingangspuffer wird zu voll) und fordert den Sender auf, die Latenz zu erhöhen (Flusskontrolle).
  • Es gibt einen einzigen langsamen Empfänger (High Ping Bastard, Heulsuse, wie sie genannt werden) unter den Empfängern, Latenz (kann) im Haushalt hinzugefügt.

zusätzlich

  • Der Nagle-Algorithmus kann die Daten des Absenders zurückhalten, bis mehr zu senden ist (um Datenrahmen effizienter zu nutzen). Zeitkritische Daten werden verzögert.
  • Ich glaube, normale Heimrouter mit WLAN können intelligente Dinge tun (verlangsamen), um den TCP-Durchsatz zwischen mehreren Clients zu glätten (die WLAN-Schnittstelle ist der Engpass, auch wenn das Spiel sie nicht verwendet). Bezieht sich auf Rundfunk / Multicasting, dh. "Andere" Daten können den TCP-Durchsatz verringern.
  • TCP ACKnowledges alles, was für eine Spielumgebung nicht notwendig ist. Es macht keinen Sinn, jedes einzelne Physik-Update zu ACKEN. Genug, um es beispielsweise einmal pro Sekunde oder ähnlich zu wissen. Wenn ein Client (oder ein Server) längere Zeit still ist, ist es Zeit zu reagieren.

Trotzdem liefert TCP den höchsten Wert für (insgesamt übertragene Daten) / (insgesamt verbrauchte Zeit). Nur, dass es nicht genau dann passiert, wenn Sie es möchten.

UDP tut nichts davon. Es wird auf Ihren Willen abgefeuert, nur dass man nicht jedes Mal damit rechnen kann - Insead muss das Ziel ankündigen, dass "Sie lange nicht mehr geschossen haben, warum?". Man kann immer noch eigene benutzerdefinierte ACK-Pakete erstellen, mehrere Datensätze in ein einziges Paket packen usw. Und auch wichtig, NAT-Traversal kontrollieren. UDP ist mit Sicherheit für Spiele mit geringer Latenz geeignet.

Sturmwind
quelle
1
Hinweis: Nagles Algorithmus kann zB für Linux deaktiviert werden .
Mucaho
Nagle kann dagegen vorgehen (und kann umgangen werden, indem jedes Paket von der Anwendung auf "Push" gesetzt wird), während Delayed Ack zu Gunsten von TCPs arbeitet. Dadurch kann der Absender mehr Bytes auf die Leitung schreiben, bis das Sendefenster voll ist (idealerweise so groß) als der Empfangspuffer ist auf der anderen Seite), unabhängig davon, ob eine Bestätigung gesehen wurde.
Jeff Meden
4
Es ist Übertragungssteuerungsprotokoll .
Ysdx
1
Tippe diese Wörter millionenfach ... thx - fixed.
Stormwind
3

Sie können das erste Diagramm von RFC 768 (UDP) mit dem ersten Diagramm von RFCP 793 (TCP) auf Seite 15 vergleichen .

Beide zeigen 16 Bit für einen "Quellport", gefolgt von 16 Bit für einen "Zielport". Beide zeigen 16 Bit für eine "Prüfsumme". Laut RFC 768 ist das "Prüfsummenverfahren von UDP das gleiche wie in TCP".

Während die UDP-Länge die Details des UDP-Diagramms zusammenfasst, ist die TCP-Länge Teil eines „96-Bit-Pseudo-Headers“, der auf den Seiten 15 und 16 beschrieben wird.

Erwarten Sie nicht, dass TCP UDP übertrifft. Das ist aus mehreren Gründen einfach unwahrscheinlich. Eines ist, dass TCP einfach mehr Bits hat. Wenn Geräte also eine bestimmte Anzahl von Bits pro Sekunde effektiv verarbeiten können, sind mehr UDP-Pakete als TCP-Pakete zulässig.

Der andere Grund ist, dass der "Drei-Wege-Handshake" von TCP bedeutet, dass der Absender auf eine Antwort warten muss. Diese Anforderung bringt zusätzlichen Overhead mit sich, den UDP nicht verarbeitet. Es gibt einen Grund, warum der Großteil Ihrer Internetkommunikation mit UDP-Kommunikation beginnt. Basis-DNS verwendet UDP, da eine Anforderung und eine Antwort in weniger Schritten ausgeführt werden können als der Drei-Wege-Handshake-Prozess von TCP. Die TCP-Funktion zum Verfolgen von verlorenen Paketen ist nicht besonders aufregend, da ein Computer einfach eine neue Anfrage stellen kann, anstatt einem Remote-System mitzuteilen, dass eine vorherige Anfrage nicht erfüllt wurde.

TOOGAM
quelle
Obwohl englische Zusammenfassungen (wie in einigen anderen Antworten zu sehen) nett sind, kann es am einfachsten sein, nur einige genaue und präzise Beschreibungen zu haben.
TOOGAM
Du meinst 16 Bits, keine Bytes!
Jcaron
Oh, dumm mich. Dies ist ein Beispiel dafür, warum technisch präzise Antworten nett sind. Sie sind leicht zu erkennen, Fehler und korrekte Informationen zu sehen. Ich habe die Antwort korrigiert. Vielen Dank @jcaron
TOOGAM
2

Überlegen Sie, was für einen Moment passiert. Um die Szenarien zu vereinfachen, haben Sie zwei Möglichkeiten, wenn Sie versuchen, eine Statusänderung zu senden (z. B. wenn Ihr Spieler gerade die Richtung geändert oder eine Waffe abgefeuert hat oder ein anderer Spieler gerade eine Bombe gezündet hat):

  1. Lassen Sie eine TCP-Sitzung geöffnet und senden Sie eine TCP-Nachricht an alle Spieler, wenn die Bombe losgehen soll (wenn möglich, siehe unten).
  2. Überwachen Sie einen UDP-Port, und senden Sie eine UDP-Nachricht an alle Spieler, unabhängig von ihrem Verbindungsstatus, wenn die Bombe losgeht

Vorausgesetzt, es wurde kein Update benötigt, wird der Zeitpunkt, zu dem dieses singuläre Update in 1 vs 2 eintrifft, nicht sehr unterschiedlich sein. Es ist eine Fahrt vom Server zum Client. Aber sagen wir, anstatt dass nur eine Bombe hochgeht, versuchen Sie ständig, die Aktivität von jemandem weiterzuleiten, der durch ein Labyrinth rennt. Weben, Ducken, Schießen usw. Bei UDP wird jede Aktion sofort in einem Datagramm gesendet. Im Falle von TCP wird jede Aktion nur dann in einem Paket gesendet, wenn der Server senden darf. Was sagt es darf senden? Platz im TCP-Fenster haben (vorausgesetzt, verzögerte Bestätigung ist aktiv), damit die Nachricht auf die Leitung gelegt werden kann. Wenn nicht, muss es warten, bis eine Bestätigung vom Client eingeht, bevor es gesendet wird.

Wie lange ist zu lang Als die Entwicklung von Multiplayer-Ego-Shootern in den späten 90ern und frühen 2000ern Einzug hielt, waren Verbindungen mit geringer Latenz nicht üblich. Ein DFÜ-Modem hätte eine typische Einweg-Latenz von 180 ms. Das Warten auf eine Bestätigung, bevor ein weiteres Update gesendet wurde, das diese Zeit auf 360 ms verdoppelte, war schmerzhaft. Sogar Anfänger konnten den Unterschied definitiv spüren. Als sich Breitbandverbindungen durchsetzten, verringerten sie die Latenz erheblich, hielten jedoch an, wenn die Bandbreite knapp war (in einigen Regionen recht häufig). Die Präferenz für eine möglichst geringe Latenz blieb also bestehen.

Moderne Heimanschlüsse und Zusammenschaltungen haben dies dahingehend geändert, dass die regionale Latenz auch zu überlasteten Tageszeiten im Bereich von 15 ms oder darunter liegt. Die Wahl von TCP anstelle von UDP wäre in den meisten Fällen unsichtbar, da die Latenz "niedrig genug" ist. Es gibt jedoch immer noch die Tendenz, dass UDP gegenüber TCP priorisiert wird, da es sich um ein Protokoll mit niedriger Latenz handelt. Daher wird UDP für die Echtzeitkommunikation für den Moment (und wahrscheinlich für einige Zeit in der Zukunft) bevorzugt.

Jeff Meden
quelle
Die Latenz wäre niedrig genug, mit der Ausnahme, dass TCP-Schreibvorgänge standardmäßig nur gesendet werden, wenn die zu schreibenden Daten einen bestimmten Schwellenwert überschreiten oder eine Zeitüberschreitung (normalerweise 200-1000 ms) auftritt. Wenn Sie TCP auf einem System mit niedriger Latenz und geringem Durchsatz benötigen, müssen Sie diese Funktion deaktivieren und sicherstellen, dass Sie nicht die ganze Zeit einzelne Bytes schreiben (z. B. behandeln Sie den TCP-Stream nicht mehr als Stream und tun dies auch so habe es stattdessen mit einzelnen Nachrichten zu tun). Sie müssen nicht auf das ACK warten, es sei denn, Ihre Puffer sind voll, was in einem typischen Echtzeitspiel sehr unwahrscheinlich ist.
Luaan
1
@Luaan Enter: das TCP-PSH-Flag. Wenn eine Anwendung den Stapel abgibt, wird das Paket sofort gesendet, ohne auf weitere Daten zu warten. Viele Anwendungen verwenden dies erfolgreich (z. B. Telnet und SSH).
Jeff Meden
2

Ich weiß, dass UDP normalerweise für Echtzeit-Multiplayer-Spiele mit hoher Datennutzung empfohlen wird.
Ist UDP in Bezug auf Geschwindigkeit und Latenz immer noch überlegen? Könnten die jüngsten TCP-Optimierungen dazu geführt haben, dass TCP eine bessere Leistung erzielt als UDP?

Ihre Annahmen sind falsch. TCP und UDP unterscheiden sich hauptsächlich in dem Modell, das sie darstellen (unzuverlässige Datagramme im Vergleich zu zuverlässigen virtuellen Datenströmen in der richtigen Reihenfolge).

Sie unterscheiden sich weder hinsichtlich des Volumens ("hoher Datennutzung") noch des Durchsatzes. TCP überträgt genau so viele Daten wie UDP, wodurch das physische Kabel leicht gesättigt wird.

In Gegenwart von Paketverlust, die zwei unterscheiden sich in der Latenz, aber nur in diesem Zustand. Ansonsten hat TCP eine genauso niedrige Latenz wie UDP (geben oder nehmen Sie vielleicht ein paar Dutzend Nanosekunden, weil der Netzwerkstapel etwas mehr Logik zu tun hat, aber das ist eher vernachlässigbar).
Es gibt einen kleinen Unterschied in der Header-Größe, so dass technisch gesehen mehr Bytes über die Leitung auf seriellen Leitungen übertragen werden müssen, aber auch dies ist eher belanglos. Es ist nur wirklich wichtig für Massentransfers, und dann sind es ungefähr 0,5% Unterschied. Die meisten Leute mit DSL-Internetzugang zu Hause leiten ihren gesamten Datenverkehr über Geldautomaten, was zu einem Protokoll-Overhead von über 10% führt (5 Steuerbytes für 48 Byte Nutzlast plus Teilrahmen), und niemand bemerkt es.

Einige Leute bauen Zuverlässigkeit auf UDP auf. Wenn ein gewisses Maß an Zuverlässigkeit gewünscht wird, jedoch keine strikte ordnungsgemäße Lieferung erforderlich ist, kann dies einen kleinen Vorteil bedeuten. Es ist jedoch immer noch umstritten, ob der Ansatz sehr sinnvoll ist, und Sie zahlen einen hohen Preis für diesen kleinen Vorteil.
Wenn Sie Clients haben, die über Hotel-WiFis oder andere "komische" Orte eine Verbindung herstellen, werden Sie feststellen, dass die allgemeine Unterstützung für TCP häufig sehr viel besser ist als für UDP.

Spiele verwenden UDP in der Regel nicht, weil es auf eine der oben genannten Arten überlegen ist - oder weil Sie durch die Implementierung von Zuverlässigkeit ohne In-Order-Funktion den Jitter um eine halbe Millisekunde reduzieren können, sondern weil Spiele (ähnlich wie IP-Telefonie) enthalten oft viele sehr flüchtige Daten, wie zum Beispiel Positionsaktualisierungen.
Diese flüchtigen Daten werden regelmäßig und schnell gelöscht, sowohl nach Ablauf der Zeit als auch nach dem nächsten eingehenden Datagramm. Dies bedeutet, dass Sie nicht mehr und nicht weniger Wert darauf legen, 100% zuverlässig (oder in Ordnung) zu sein.

Angenommen, ein Netzwerkpaket wird in einem Dienst gelöscht, der mit regelmäßigen Updates (Shooter-Spiel, Telefon, Video-Chat) ausgeführt wird. In diesem Fall ist es wenig sinnvoll, eine Zeitüberschreitung für die Bestätigung zu haben und das Paket erneut zu senden friere alles auf der anderen Seite ein, während du auf das Eintreffen des erneut gesendeten Pakets wartest. Das ist viel zu beunruhigend und nicht gut.

Stattdessen betrachten Sie das Paket einfach als verloren und fahren fort, wobei Sie die Daten aus dem nächsten Paket übernehmen, das es durchläuft, und in der Zwischenzeit nach besten Kräften die Tatsache verbergen, dass ein Paket für den Benutzer verloren gegangen ist. Interpolation, tote Rechnung, Sie nennen es.

Beachten Sie übrigens, dass Paketverlust ein normaler Zustand ist. Während IP im Allgemeinen "ziemlich zuverlässig" ist, können gelegentlich verworfene Pakete auftreten und werden auftreten . Während Pakete, die verloren gehen, normalerweise eher selten sind (<1% hier), handelt es sich nicht um etwas Außergewöhnliches oder Theoretisches oder um einen Hinweis darauf, dass etwas kaputt ist. Das ist völlig normal.
Jede TCP-Massenübertragung enthält beispielsweise unbedingt verlorene Pakete (so funktioniert die Überlastungskontrolle).

Damon
quelle
2

In einem MPG mit hoher Bandbreite ist es Ihnen egal, ob Sie ein Paket verpasst haben, das Ihnen den Ort und die Gesundheit von Monster Nr. 425 anzeigt, da Sie in Sekundenbruchteilen ein weiteres Update erhalten. In diesem Beispiel lässt UDP TCP dumm aussehen, weil Sie auf veraltete Daten warten müssen.

In demselben Spiel sollen die Patches genau so angezeigt werden, wie sie entworfen wurden. In TCP ist bereits die Funktion "Benachrichtigen, ob ein Fehler aufgetreten ist" integriert, die automatische Wiederholungsversuche und überprüfte Fehler ermöglicht. Sie können es in UDP tun, aber warum die Technologie neu erstellen?

Hier finden Sie eine einfache Beschreibung der Vorgänge.

UDP - Isoliere Chunk O'Data.
Mach ein Paket.
In IP kapseln.
Es versenden.

TCP - Isolieren Sie einen Stream O'Data.
Machen Sie ein Paket von der Vorderseite des Streams.
In IP kapseln.
Warten Sie auf Leerzeichen im TCP-Fenster.
Es versenden.
Versenden Sie so lange, bis eine Quittung eingeht oder die Zeit abgelaufen ist.
Bleiben Sie im TCP-Fenster, bis eine Quittung oder ein Timeout eingeht.

Der Versand bedeutet nur, dass es durch die lokale Netzwerkkarte geschafft hat, nicht mehr.

Ein TCP-Empfangsempfang garantiert sowohl den Datenempfang als auch den freien Platz im Fenster für das nächste Paket.

Ein erneutes (leichtes) Senden erhöht die Wahrscheinlichkeit eines möglichen Empfangs.

TCP-Pakete werden auf der anderen Seite als geordneter Datenstrom wieder zusammengesetzt. UPD-Pakete werden als unterschiedliches Paket empfangen. Das Protokoll behält die Ordnung nicht bei.

TCP ist gut für das Pushen erforderlicher Daten und großer Datenmengen geeignet. TCP informiert über einen anhaltenden Fehler. TCP drosselt sich selbst durch verstopfte Leitungen (siehe Fenster). TCP hat Handshakes, um die Initialisierung zu verlangsamen. TCP benötigt vor der Übertragung eine "Verbindung".

UDP überträgt die Daten einfach auf die Leitung und Sie können fortfahren, ohne auf Fenster und Neuübertragungen zu warten. UDP sprengt Daten mit voller Geschwindigkeit in eine verstopfte Pipe, unabhängig davon, wie viele Daten verloren gehen.

Ich habe ein kommerziell angewendetes UDP Multicast File Transport Utility entworfen und geschrieben. Ich habe an IP-Stacks gearbeitet. Dies sind nur Grundlagen, ohne Kleinigkeiten. "Steckdosen, MTUs und andere lustige Spielzeuge" zu erklären, war ein wenig jenseits dessen, was für diese Frage nützlich sein würde.

Ps (Ich kann keine Kommentare hinzufügen, um auf Kommentare zu antworten) UDP eignet sich auch für Daten, die wünschenswert, aber nicht erforderlich sind. Die Vorwärtsfehlerkorrektur ist ein Beispiel dafür, viele unnötige, aber wünschenswerte Pakete.

dusc2don
quelle
3
Ihre Meinung zu "veralteten" Daten ist gut. TCP ist gut für "besser spät als nie" -Daten, aber UDP ist gut für Daten, die nützlich sind, wenn sie das Ziel schnell erreichen, aber nutzlos, wenn dies nicht der Fall ist.
Supercat
1

Haben alle TCP-optimierten Router dafür gesorgt, dass TCP eine bessere Leistung als UDP erbringt?

Eine weitere Frage ist: Bedeutet "datenlastig", dass Sie häufig Szenen laden?

Wenn ja, müssen Sie möglicherweise große Datenmengen (> 1 KB) intensiv senden, wobei TCP möglicherweise viel effizienter ist, da die Netzwerkkarten insbesondere auf der Serverseite verschiedene Auslagerungen mit derselben Anzahl von Zyklen bereitstellen. Eine User Space-Anwendung kann große Schreibvorgänge mit TCP ausführen, während in UDP der Versuch, mehr als MTU-Header-Größenbytes zu senden, zu einer IP-Fragmentierung und anderen Overheads führt, die die Leistung beeinträchtigen

Vadim Suraev
quelle
Es ist ein "Voxel" -Spiel, also muss es eine Menge Szenendaten senden.
KaareZ
@KaareZ Nun, wahrscheinlich möchten Sie diese in diesem Fall sowieso als einzelne unabhängige Nachrichten mit Ihren eigenen Neuübertragungsmechanismen senden. Minecraft startete unter TCP und war über das Internet so gut wie nicht spielbar. Die Umstellung auf UDP war für die meisten ein erfreulicher Anlass. Die Hauptidee ist, dass beim Senden von 20 Voxeldatenblöcken und wenn der erste "verloren" geht, die anderen 19 Blöcke nicht daran gehindert werden, angezeigt zu werden, sobald Sie die Daten erhalten. Wenn Sie feststellen, dass der erste fehlt, senden Sie ihn erneut. Bei TCP werden mindestens alle dieser 19 blockiert und im schlimmsten Fall erneut übertragen.
Luaan
2
@Luaan Minecraft hat für das aktuelle Gameplay nicht auf UDP umgestellt. Sogar die neuesten Versionen verwenden noch TCP. Kein glücklicher Anlass ... :( Der einzige Teil von Minecraft, der UDP verwendet, ist die Serverliste, um einzelne Server zu
pingen
1

Weder UDP noch TCP (oder eine andere Variante) sind absolut überlegen , auch nicht in Bezug auf Geschwindigkeit / Latenz. Ihre Wahl muss in Abhängigkeit von den Anforderungen Ihrer Anwendung getroffen werden. Zu diesem Zweck sollten Sie die Funktionen vergleichen, die jedes Protokoll bietet, und dabei feststellen, dass mehr Funktionen einen höheren Aufwand bedeuten. Wenn das Ziel darin besteht, die Latenz zu minimieren oder die Geschwindigkeit zu maximieren, sollten Sie ein Protokoll mit möglichst wenigen Funktionen auswählen, aber die für Ihre Anforderungen erforderlichen wesentlichen Funktionen beibehalten.

Ein Vergleich der Protokolle

Im Allgemeinen bietet UDP (User Datagram Protocol) die geringste Anzahl von Funktionen. Es ist einfach, dass Sie Daten ohne irgendeine Art von Quittung / Bestätigung senden.

Andererseits bietet TCP (Transmission Control Protocol) die meisten Funktionen, die für eine zuverlässige, verbundene Kommunikation erforderlich sind. Bei einer TCP-Kommunikation werden Duplikate oder mehr von Paketen gesendet und mit Bestellinformationen versehen. Nach dem Empfang am Ziel muss eine ACK (Bestätigung) zusammen mit Informationen darüber, welche Pakete verloren gegangen sind, zurückgesendet werden, damit der ursprüngliche Absender diese verlorenen Pakete erneut senden kann. Wenn ich mich richtig erinnere, müssen möglicherweise sogar ACK-Pakete bestätigt werden, um eine ordnungsgemäße Zuverlässigkeit zu gewährleisten.


Beispiel: Skype-Konferenzgespräch

Bei einer Skype-Telefonkonferenz ist es nicht wichtig, dass alle Video- und Audiodaten zuverlässig gesendet / empfangen werden. Heutzutage leistet UDP einen großartigen Beitrag zur Minimierung von Paketverlusten. Wichtig zu wissen ist, dass es in UDP absolut keine Garantie dafür gibt, ob die Übertragung erfolgreich war oder nicht. Für Audio- / Videodaten in einer Telefonkonferenz ist UDP die richtige Wahl, da es uns mehr darum geht, Echtzeitdaten (dh die neuesten) abzurufen. Wenn hier und da ein paar Pakete verloren gehen, wird die Kommunikation nicht dramatisch unterbrochen.

In einer Telefonkonferenz können jedoch Sofortnachrichten (Instant Messages) oder Dateien gesendet werden. In diesen Fällen ist Zuverlässigkeit eine notwendige Voraussetzung, um sicherzustellen, dass Dateien und Nachrichten nicht beschädigt werden oder verloren gehen. Für IMs können Sie das nicht brauchen verbundenen Zustand , dass TCP bietet. Ein Zwischenprotokoll wie RUDP (Reliable UDP) kann ausreichend sein. Für Dateien kann es jedoch erforderlich sein, den von TCP bereitgestellten Verbindungsstatus zu haben.


Implementierungsoptionen

Wenn Sie eine komplexe Anwendung haben oder Ihre Kommunikation optimieren müssen, ist es hilfreich, mit einer UDP-Kommunikation zu beginnen. Anschließend können Sie alle Funktionen hinzufügen, die Sie benötigen. Dies gibt Ihnen die größte Kontrolle über Ihre Netzwerkkommunikation.

Wenn Sie eine einfache Anwendung haben, bei der keine Optimierung erforderlich ist, können Sie eine Standardanwendung (UDP oder TCP) verwenden, um Ihre Anforderungen zu erfüllen. Das würde Ihnen erlauben, sich wichtigeren Angelegenheiten zuzuwenden.

Nicholas Miller
quelle
1

Ich habe viele Kommentare bemerkt, in denen Leute glauben, dass TCP-Pakete größer sind als UDP-Pakete. Vertrau mir nicht einfach, lies die Dokumentation. Das Protokoll lautet wie folgt: Einige Bytes für den Ethernet-Header (2 Bytes Nachrichtentyp, 48-Bit-MAC, 6 Bytes) (für Wifi kann der Header abweichen) 20 Bytes für IP 20 Bytes für TCP oder UDP x Bytes für die Daten x Bereich von 0 bis ungefähr 1500 (siehe MTU) Zuletzt die Prüfsumme, um sicherzustellen, dass in diesem Ethernet-Paket keine Beschädigung aufgetreten ist.

TCP ermöglicht das Senden eines größeren "Stream" -Pakets von ca. 64K. Dieser "große" Block wird tatsächlich in viele kleinere Ethernet-Pakete zerhackt.

Joust6809
quelle
Versuchen Sie vorzuschlagen, dass UDP- und TCP-Header dieselbe Größe haben?
Cameron