Warum ist UDP mit Zuverlässigkeit (auf Anwendungsebene implementiert) kein Ersatz für TCP?

25

TCP bietet Zuverlässigkeit auf Transportebene, UDP nicht. UDP ist also schnell. Ein Protokoll auf Anwendungsebene kann jedoch einen zuverlässigen Mechanismus implementieren, wenn UDP verwendet wird.

Warum ist UDP mit Zuverlässigkeit (in der Anwendungsschicht implementiert) in diesem Sinne kein Ersatz für TCP, wenn UDP schneller als TCP ist, obwohl Zuverlässigkeit erforderlich ist?

mallea
quelle
6
Warum stellt jede Anwendung ihren eigenen Zuverlässigkeitsmechanismus bereit, wenn sie sich einfach auf ein anderes weit verbreitetes Protokoll wie TCP verlassen können?
Nakrule
14
und wie schlagen Sie vor, Zuverlässigkeit auf Anwendungsebene zu implementieren, ohne den Stack zu verlangsamen?
JFL
6
" Da der UDP-Header kleiner als der von TCP ist, können wir die Datengröße ausnutzen. " Das Problem bei dieser Überlegung ist, dass Sie wahrscheinlich einen großen Teil der UDP-Nutzdaten mit Protokoll-Headern auf Anwendungsebene essen werden, die die verwendbaren Daten in der verringern UDP-Payload. Der Unterschied zwischen der TCP- und UDP-Headergröße beträgt nur 12 Byte. UDP ist auch wirklich für kleine Nutzlasten ausgelegt, z. B. 576 Bytes. Denken Sie daran, dass UDP einfach Datagramme verliert. Je mehr Daten in einem Datagramm vorhanden sind, desto mehr Daten gehen verloren, wenn ein Datagramm verloren geht.
Ron Maupin
21
Stapelüberlauf ist weit verbreitet von Programmierern, die versuchen und scheitern, TCP-ähnliche Protokolle mit UDP zu erstellen. Die erfahreneren Programmierer fordern sie auf, es aufzugeben und einfach TCP zu verwenden. Sie alle denken, dass sie einen besseren Job machen können, aber es ist höchst unwahrscheinlich.
Ron Maupin
11
Ich weiß, dass dies nicht direkt Teil Ihrer Frage ist, aber ein Grund, warum UDP besser sein kann, ist, dass Sie nur die Zuverlässigkeitsteile implementieren können, die Sie benötigen. Mit TCP erhalten Sie Zuverlässigkeit bei Bestellung und Lieferung. Dies bedeutet, dass TCP Probleme haben kann, während es darauf wartet, dass eine vorherige Nachricht erneut gesendet wird. Mit UDP können Sie entscheiden, dass nur die Zustellung gewünscht wird. Wenn jedoch eine Nachricht nicht in der richtigen Reihenfolge eingeht, warten Sie nicht auf die fehlenden, sondern verwerfen sie einfach. Die Gefahr besteht darin, dass versucht wird, TCP 100% zu replizieren. Verwenden Sie in diesem Fall einfach TCP.
William Mariager

Antworten:

47

TCP ist ungefähr so ​​schnell, wie Sie mit seinen Zuverlässigkeitseigenschaften etwas anfangen können. Wenn Sie beispielsweise nur Sequenzierung und Fehlererkennung benötigen, kann UDP einen einwandfreien Dienst leisten. Dies ist die Grundlage für die meisten Echtzeitprotokolle wie Sprache, Video-Streaming usw., bei denen Verzögerung und Jitter wichtiger sind als die "absolute" Fehlerkorrektur.

Grundsätzlich sagt TCP, dass man sich irgendwann auf seine Streams verlassen kann. Wie schnell das ist, hängt von den verschiedenen Timern, Geschwindigkeiten usw. ab. Die zur Behebung von Fehlern benötigte Zeit kann unvorhersehbar sein. Die grundlegenden Vorgänge sind jedoch so schnell wie möglich, wenn keine Fehler vorliegen. Wenn ein System etwas über die Art der wahrscheinlichen Fehler weiß, kann es möglicherweise etwas tun, was mit TCP nicht möglich ist. Wenn beispielsweise Einzelbitfehler besonders wahrscheinlich sind, können Sie für diese Bitfehler eine fehlerkorrigierende Codierung verwenden. Dies ist jedoch in der Verbindungsschicht viel besser implementiert. Ein weiteres Beispiel: Wenn kurze Bursts mit Gesamtpaketverlust häufig auftreten, können Sie dies mit Mehrfachübertragung beheben, ohne auf den Verlust zu warten. Dies ist jedoch offensichtlich bandbreitenintensiv. Oder verlangsamen Sie die Geschwindigkeit, bis die Fehlerwahrscheinlichkeit vernachlässigbar ist: auch in Bezug auf die Bandbreite teuer. Schlussendlich,

In Bezug auf die Implementierung werden Sie feststellen, dass der in TCP investierte Programmierer jahrhundertelang schneller ist als alles, was Sie sich leisten können, und auch in den dunklen Randfällen zuverlässiger ist.

TCP bietet: eine allgegenwärtige Verbindungsmethode (unerlässlich, wenn die kommunizierenden Systeme keine gemeinsame Kontrolle haben), die einen zuverlässigen, geordneten (und deduplizierten) Zwei-Wege-Bytestrom mit Fenstern und Überlastungskontrolle über Multi-Hop-Netze mit beliebiger Entfernung ermöglicht.

Wenn für eine Anwendung keine Allgegenwart erforderlich ist (Ihre Software wird auf beiden Seiten ausgeführt) oder wenn nicht alle TCP-Funktionen erforderlich sind, verwenden viele Benutzer andere Protokolle, häufig zusätzlich zu UDP, profitabel. Beispiele hierfür sind TFTP (minimalistisch, mit wirklich ineffizienter Fehlerbehandlung), QUIC, mit dem der (noch als experimentell gekennzeichnete) Overhead verringert werden soll, und Bibliotheken wie lidgren, mit denen genau gesteuert werden kann, welche Zuverlässigkeitsmerkmale erforderlich sind. ]

Jonathanjo
quelle
7
Benutzerdefinierte "UDP mit Zuverlässigkeit" -Protokolle sind auch in Videospielen äußerst verbreitet. Es gibt eine Menge Netzwerkbibliotheken mit verschiedenen Implementierungen. In der Regel möchten sie, dass Pakete bestellt werden und eine Fehlerkorrektur durchgeführt wird, ohne dass verlorene Pakete erneut übertragen werden müssen (und Verzögerungen für alle zukünftigen Pakete empfangen werden müssen).
BlueRaja - Danny Pflughoeft
Klingt so, als würden Sie sagen, "TCP ist die optimale allgemeine Lösung, um es nativ zu unterstützen". +1
ikegami
1
@ BlueRaja-DannyPflughoeft Und manchmal möchten Sie zuverlässige ungeordnete Pakete (z. B. visuelle Effekte, die auf Spieler in der Nähe angewendet werden).
User253751
@ BlueRaja-DannyPflughoeft Wenn Sie eine typische Beispielprotokollbibliothek haben, werde ich diese gerne in die Antwort aufnehmen
Jonathanjo,
1
@jonathanjo Eines, das ich verwendet habe, ist lidgren , das 5 verschiedene Zustellmethoden unterstützt (scrollen Sie nach unten) . Unity und Unreal Engine verfügen außerdem über eigene Netzwerk-APIs, die auf UDP basieren.
BlueRaja - Danny Pflughoeft
10

UDP mit Zuverlässigkeit kann in der Tat ein Ersatz für TCP sein. Wir haben bereits ein Beispiel dafür: Es heißt QUIC .

Aus Wikipedia:

Unter anderem verbessert QUIC die Leistung von verbindungsorientierten Webanwendungen, die derzeit TCP verwenden. Dazu werden mehrere Multiplexverbindungen zwischen zwei Endpunkten über UDP (User Datagram Protocol) hergestellt.

Der Vorteil der Verwendung von UDP gegenüber der Erstellung eines brandneuen Transportschichtprotokolls besteht darin, dass Router und andere Netzwerkgeräte dies bereits verstehen.

Andrea Corbellini
quelle
QUIC hat ein anderes Merkmal als TCP. In einigen Szenarien (zuverlässiges Netzwerk oder keine Verschlüsselung erforderlich) es ist tatsächlich langsamer: quora.com/...
freakish
Sie können der Liste auch WebRTC-Datenkanäle hinzufügen, die UDP über sctp verwenden. In der Tat, wenn UDP-Verbindungen zwischen Peers nicht möglich sind, wird WebRTC ein Failover auf TCP durchführen, was zu einem spürbaren Leistungseinbruch führt.
JSON
@freakish langsamer ist in diesem Fall eine Verallgemeinerung. Beispielsweise fügt QUIC den Paketen zusätzliche Daten hinzu, um die erneute Übertragung zu verringern, was sich auf den Durchsatz, aber nicht auf die Latenz auswirkt.
JSON
4

Sie können UDP verwenden, um die TCP-Funktionalität auf der Anwendungsebene zu implementieren (Zuverlässigkeit, Anpassungsfähigkeit). Genauso gut können Sie TCP verwenden, es sei denn, etwas, das Ihre Anwendung wirklich benötigt, kann nicht mit TCP durchgeführt werden. Wenn Sie diese Funktionen selbst implementieren, erhalten Sie höchstwahrscheinlich ein viel schlechteres Ergebnis als mit TCP. Der zusätzliche Aufwand verringert auch die Gesamteffizienz.

TCP ist nicht langsam - es ist lediglich ein Handshake vor dem Senden und ein Anpassen des Übertragungsfensters an den Kanal erforderlich. Es kann seinen Durchsatz zum jeweiligen Übertragungskanal sehr gut formen und sich an Änderungen während des Flusses anpassen, was UDP (allein) nicht kann.

Protokolle oberhalb der Transportschicht sind hier jedoch nicht zum Thema.

Zac67
quelle
3
"Sie könnten UDP verwenden, um TCP-Funktionalität auf der Anwendungsebene zu implementieren (Zuverlässigkeit, Anpassungsfähigkeit)" - Ich glaube, so sind QUIC, µTP und oft SCTP bereits implementiert. (Trotzdem betrachte ich sie normalerweise als in der oberen Hälfte der Transportschicht, während UDP in der unteren Hälfte sitzt.)
grawity
1
@grawity Das hängt von Ihrem POV ab - aus Sicht der Anwendung ist eine Zwischenschicht eine Erweiterung der Transportschicht. Formal und aus der Sicht des Netzwerks (Geräts) ist dies alles Teil der Anwendungsebene.
Zac67
4

In einem sauberen Netzwerk sind sie ziemlich gleichwertig. Es gibt Fälle, in denen TCP für einige Zeit hängen bleibt (hat jemand jemals ein Einfrieren des HTTP-Bildschirms beim Laden gesehen?), Aber es liefert keinen Müll oder vermischt Pakete und gibt selten vollständig auf.

UDP kann der Anwendungsebene mehr Kontrolle über den Datenverkehr geben, was sehr viel Arbeit kostet.

Die Antwort auf Ihre Frage ist, manchmal wird es so gemacht. Spiele, die eine geringe Latenz erfordern, tun oft genau das. Es ist viel mehr Arbeit, aber die Möglichkeit, genau zu steuern, wie viele ausstehende Pakete Sie haben können und wie oft sie wiederholt werden, lohnt sich oft.

Insgesamt besteht der Unterschied darin, dass TCP eine sehr gute Allzweckimplementierung ist, aber UDP kann bestimmte Aufgaben erfüllen, die TCP entweder nur sehr schlecht oder gar nicht erfüllt - zum Beispiel:

  • NIEMALS aufgeben (bei TCP hängt die Verbindung manchmal und Sie müssen die Verbindung trennen und neu starten)
  • Senden Sie einen schnellen Strom von Paketen, für die keine Antworten erforderlich sind, und verpassen Sie gelegentlich einige (wobei nur das neueste Paket wichtig ist und alle anderen verworfen werden können) "Springen" statt in jedem Schritt, aber Sie erhalten das gleiche Ergebnis schneller und zuverlässiger.
  • Umgang mit fragwürdigen Netzwerken durch Analysieren von Paketverlusten und dynamisches Ändern der Häufigkeit und des Zeitpunkts, zu dem Sie es erneut versuchen - möglicherweise sogar der maximalen Paketgröße.

Aber im Allgemeinen lohnt es sich nicht, TCP ist ziemlich optimal. Warum also all die zusätzliche Arbeit auf sich nehmen und eine (große) Chance auf das Hinzufügen von Fehlern und Sicherheitslücken aufbauen?

Bill K
quelle
3

UDP ist nicht schnell, weil es UDP ist. TCP ist nicht langsam, weil es TCP ist.

Beide Protokolle sind mit bestimmten Garantien ausgestattet und Raw-TCP bietet mehr Garantien als Raw-UDP.

Und die Faustregel lautet: Der Preis für Garantien ist Leistung .

Es gibt nichts, was Sie daran hindert, TCP-Garantien über UDP zu implementieren. Aber dann bekommt man mehr Garantien und muss den Preis bezahlen. Daher reduzieren Sie die Leistung auf TCP oder schlechter (aufgrund von UDP-Overhead). Es sei denn, Sie kennen eine bessere TCP-Implementierung, was unwahrscheinlich ist. Und wenn Sie es dann tun (hoffnungsvoll), enthüllen Sie es und wir machen das Standard-TCP schneller. Und wir sind wieder da, wo wir angefangen haben. :)

Sie können auch mit diesen Garantien spielen. Ändern Sie dies leicht, ändern Sie das leicht. Und dann haben Sie ein Protokoll wie QUIC, das über UDP läuft und TCP + TLS sehr ähnlich ist. In vielen Fällen ist es schneller als TCP (obwohl es laut diesem Artikel eine Latenz von bis zu 5% und eine Pufferung von bis zu 15% gibt, was IMO keine große Sache ist), aber in einigen Szenarien (z. B. zuverlässiges Netzwerk oder keine Notwendigkeit für Verschlüsselung) ist dies tatsächlich der Fall langsamer (siehe Erklärung hier ).

Sie können diese Garantien auch schwächen, und dann ist es sinnvoller. Angenommen, Sie streamen und alte Pakete sind nicht interessant. Nur die aktuellste. Aber die Überlastung ist immer noch wichtig. Sie nehmen also einige Garantien von TCP, aber nicht alle. Und ja, die Leute machen das tatsächlich (zB Echtzeitspiele). Dies führt zu einer besseren Leistung auf Kosten einiger Garantien.

verrückt
quelle
1

Ihre Idee wäre gut im Weltraum.

Die richtige Antwort lautet "es kommt darauf an" und "weil dies das gesamte Netzwerk beschädigen würde". TCP / IP ist sehr netzwerkfreundlich und passt sich automatisch an die richtige Geschwindigkeit an, um schnell zu sein, generiert jedoch keine Tonnen von ICMP-Rückgabepaketen.

Wenn ein Router mit nicht genügend RAM plötzlich eine Menge von Paketen empfängt, beispielsweise von Tsunami, Bittorrent oder FDT, wird diese verworfen und ein kleines Paket zur Fehlerbestätigung an den Absender zurückgeschickt. Jetzt muss Ihr UDP-Server diesen Teil manuell verfolgen und erneut übertragen. Einige ISP-Router formen Bittorrent so sehr, dass dies dem Tsunami schadet.

Das Tsunami-Protokoll verwendet UDP mit einem Kontrollkanal in TCP. http://tsunami-udp.sourceforge.net/ Ich fand eine Studie, die zeigt, dass es langsamer ist als ein Ding namens FDT.

Das legendäre Fast Data Transfer (FDT) -Protokoll von CERN ist in der Lage, jedes Netzwerk mit mehreren TCP-Streams zu überlasten. Wahrscheinlich ist es schneller, weil es weniger Neuübertragungen verursacht, als der Tsunami, der das Netzwerk mit so viel UDP überflutet, es teilweise nicht bis zum Ende schafft.

UDP wird von unzuverlässigen Anwendungen verwendet: Audio-Streaming, Spieleingabe / -Update-E / A, "Ping" ist tatsächlich ICMP, wird aber nicht garantiert, Bittorrent, Mosh-SSH ist äußerst reaktionsfähig, VOIP-Telefonie, Multicast, DNS wird über UDP-AFAIK gesendet. Alles, was nichts gegen das ein oder andere fehlende Paket hat und sofort "aufholen" kann.

TCP / IP war wirklich die Killer-Erfindung, die es App-Entwicklern ermöglichte, diese einfach zu setzen und zu vergessen. Ein Socket ist ein Paar von IP-Adressen und Ports, die eingerichtet werden können und stunden-, tag- oder sogar wochenlang bestehen bleiben, ohne dass eine erneute Verbindung hergestellt werden muss. E-Mail, Web, IRC und buchstäblich alle Killer-Apps verwenden TCP. Es kann jedoch zu merkwürdigen Download-Pausen kommen, die sich plötzlich beschleunigen ... und im Weltraum kann es zu Zeitüberschreitungen bei den Verbindungen kommen, sodass Transfers im Tsunami-Stil am besten für interstellare Dateitransfers geeignet sind - Sie könnten sich dort auf etwas befinden !!

Der Beweis ist in den abschließenden Bemerkungen dieses Wissenschaftsstudien-Auszuges zu finden, in denen die zunehmende Distanz erwähnt wird, auf die ich mich beziehe: Deep Space Von: https://uscholar.univie.ac.at/get/o:300623.pdf

Ohne Überlastung ist die Leistung von FDT und GridFTP mit TCP höher als die von Tsunami und UDT. Der höchste Durchsatz von FDT liegt bei 2,34 Gb / s mit einer RTT von 1 ms, nimmt jedoch nach 100 ms rasch ab, verglichen mit GridFTP, das eine bessere Leistung als FDT erzielt, wenn die RTT der Verbindung länger als 100 ms ist. Interessanterweise nahm der Durchsatz des Tsunami mit zunehmender RTT nicht ab, was zeigt, dass er mit zunehmender RTT die effektivste Überlastungskontrolle aufweist.

Andererseits ... gibt es tatsächlich ein Space-Protokoll, das einer E-Mail ähnelt und besser für den Space geeignet ist. Die Apps müssen keine Timeout-Werte wie für immer beachten.

Tomachi
quelle
0

TCP! = UDP + Zuverlässigkeit

TCP ist nicht einfach UDP mit zusätzlicher Zuverlässigkeit. TCP bietet mehr Funktionen als nur Zuverlässigkeit. Sie können in vielen RFCs darüber lesen.

Jedes dieser Merkmale "könnte" auf der Anwendungsschicht implementiert werden. Irgendwann wird es ein Punkt, an dem Sie anfangen, das Rad neu zu erfinden.

Um nur einige Features zu nennen, die TCP hat ...

  • Herstellen und Beenden von Verbindungen: Führt Handshakes und Verbindungsabbrüche durch

  • Flusskontrolle: Stellt sicher, dass Sender und Empfänger mit Raten senden, bei denen beide die Datenrate verarbeiten können.

  • Ende-zu-Ende-Überlastungskontrolle: Ermöglicht es Endknoten, ihren Durchsatz basierend auf Verlusten zu drosseln. Lesen Sie mehr über langsamen Start, Vermeidung von Staus und schnelle Wiederherstellung.

Meiner Erfahrung nach wird UDP verwendet, wenn es um Geschwindigkeit und Zuverlässigkeit geht. Sie können eine Zuverlässigkeitsstufe auf Anwendungsebene hinzufügen, die nicht zu 100% so zuverlässig ist wie TCP. Wenn Sie beispielsweise weiterhin eine schnelle Leistung wünschen, können Sie eine Vorwärtsfehlerkorrektur (Forward Error Correction, FEC) implementieren, bei der Sie die Daten mehrmals übertragen. Sie erhalten immer noch eine gute Leistung und ein gewisses Maß an Zuverlässigkeit (beachten Sie die recht gute TCP-Zuverlässigkeit), ohne den gesamten hin- und hergehenden Chat, um verlorene Pakete zu erhalten. Der Nachteil ist, dass es die Netzwerknutzung erhöht, aber für Echtzeitanwendungen wie Spiele oder Streaming geeignet sein kann.

jaybers
quelle
Sie könnten diese zusätzlichen Funktionen so beschreiben, dass es letztendlich um Zuverlässigkeit geht.
user207421