Was verwenden Sie, wenn Sie zuverlässiges UDP benötigen?

Wenn Sie eine Situation haben, in der eine TCP-Verbindung möglicherweise zu langsam ist und eine UDP-Verbindung möglicherweise zu unzuverlässig ist, was verwenden Sie? Es gibt verschiedene standardmäßige zuverlässige UDP-Protokolle, welche Erfahrungen haben Sie damit?

Bitte besprechen Sie ein Protokoll pro Antwort und wenn jemand anderes den von Ihnen verwendeten bereits erwähnt hat, dann erwägen Sie, sie zu wählen und einen Kommentar zu verwenden, falls erforderlich.

Ich interessiere mich für die verschiedenen Optionen hier, von denen TCP am einen Ende der Skala und UDP am anderen Ende ist. Verschiedene zuverlässige UDP-Optionen sind verfügbar und jeder bringt einige Elemente von TCP zu UDP.

Ich weiß, dass TCP oft die richtige Wahl ist, aber eine Liste der Alternativen ist oft hilfreich, um zu dieser Schlussfolgerung zu kommen. Dinge wie Enet, RUDP usw., die auf UDP basieren, haben verschiedene Vor- und Nachteile, hast du sie benutzt, was sind deine Erfahrungen?

Zur Vermeidung von Zweifeln gibt es keine weiteren Informationen, dies ist eine hypothetische Frage und eine, von der ich hoffte, dass sie eine Liste von Antworten entlocken würde, die die verschiedenen Optionen und Alternativen für jemanden, der eine Entscheidung treffen muss, detailliert darlegte.

Es ist schwierig, diese Frage ohne zusätzliche Informationen zu der Problemdomäne zu beantworten. Zum Beispiel, welche Datenmenge verwenden Sie? Wie oft? Was ist die Art der Daten? (z. B. ist es einzigartig, einmalige Daten? Oder ist es ein Strom von Beispieldaten? etc.) Für welche Plattform entwickeln Sie? (z. B. desktop / server / embedded) Um herauszufinden, was Sie mit “zu langsam” meinen, welches Netzwerkmedium benutzen Sie?

Aber in (sehr!) Allgemeinen Begriffen denke ich, dass Sie wirklich versuchen müssen, tcp für Geschwindigkeit zu schlagen, es sei denn, Sie können einige harte Annahmen über die Daten machen, die Sie senden möchten.

Wenn beispielsweise die Daten, die Sie senden möchten, so sind, dass Sie den Verlust eines einzelnen Pakets tolerieren können (z. B. regelmäßig gesampelte Daten, bei denen die Abtastrate um ein Vielfaches höher ist als die Bandbreite des Signals), können Sie dies wahrscheinlich tun opfern Sie eine gewisse Zuverlässigkeit der Übertragung, indem Sie sicherstellen, dass Sie Datenkorruption erkennen können (zB durch die Verwendung eines guten CRC)

Aber wenn Sie den Verlust eines einzelnen Pakets nicht tolerieren können, dann müssen Sie damit beginnen, die Arten von Zuverlässigkeitstechniken einzuführen, die tcp bereits hat. Und ohne eine vernünftige Menge an Arbeit zu leisten, werden Sie vielleicht feststellen, dass Sie damit beginnen, diese Elemente in eine User-Space-Lösung mit allen damit verbundenen Geschwindigkeitsproblemen zu integrieren.

Was ist mit SCTP ? Es ist ein Standard-Protokoll von der IETF (RFC 4960)

Es hat Chunking-Fähigkeit, die für die Geschwindigkeit helfen könnte.

Update: Ein Vergleich zwischen TCP und SCTP zeigt, dass die performanceen vergleichbar sind, wenn nicht zwei Schnittstellen verwendet werden können.

Update: ein schöner einleitender Artikel .

ENET – http://enet.bespin.org/

Ich habe mit ENET als zuverlässiges UDP-Protokoll gearbeitet und eine asynchrone Socket-freundliche Version für einen Client von mir geschrieben, der es in ihren Servern verwendet. Es funktioniert ganz gut, aber ich mag nicht den Overhead, den der Peer-to-Peer-Ping zu ansonsten ungenutzten Verbindungen hinzufügt; Wenn Sie viele Verbindungen haben, die regelmäßig alle anpingen, ist das viel Arbeit.

ENET bietet Ihnen die Möglichkeit, mehrere “Kanäle” von Daten zu senden, und die gesendeten Daten sind unzuverlässig, zuverlässig oder sequenziert. Es umfasst auch das oben erwähnte Peer-to-Peer-Ping, das als Keep Alive fungiert.

Wir haben Kunden aus der Verteidigungsindustrie, die UDT (UDP-basierte Datenübertragung) verwenden (siehe http://udt.sourceforge.net/ ) und sind sehr zufrieden damit. Ich sehe, dass es eine freundliche BSD-Lizenz gibt.

RUDP – Zuverlässiges Benutzer-Datagramm-Protokoll

Dies bietet:

  • Bestätigung der empfangenen Pakete
  • Windowing und Staukontrolle
  • Neuübertragung von verlorenen Paketen
  • Overbuffering (schneller als Echtzeit-Streaming)

Es scheint etwas konfigurierbarer in Bezug auf Alives zu sein, aber ENet, aber es gibt Ihnen nicht so viele Optionen (dh alle Daten sind zuverlässig und sequenziert nicht nur die Bits, die Sie entscheiden sollten). Es sieht ziemlich einfach zu implementieren aus.

Wie andere darauf hingewiesen haben, ist Ihre Frage sehr allgemein gehalten, und ob etwas “schneller” ist als TCP, hängt sehr von der Art der Anwendung ab.

TCP ist im Allgemeinen so schnell, wie es für ein zuverlässiges Streaming von Daten von einem Host zu einem anderen ist. Wenn Ihre Anwendung jedoch viele kleine Verkehrsbrüche ausführt und auf Antworten wartet, ist UDP möglicherweise besser geeignet, um die Latenz zu minimieren.

Es gibt einen leichten Mittelweg. Nagles Algorithmus ist der Teil von TCP, der dafür sorgt, dass der Sender den Empfänger eines großen Datenstroms nicht überlastet, was zu Überlastung und Paketverlust führt.

Wenn Sie die zuverlässige Bereitstellung von TCP in der richtigen Reihenfolge sowie die schnelle Antwort von UDP benötigen und sich keine Sorgen über die Überlastung beim Senden großer Datenströme machen müssen, können Sie den Nagle-Algorithmus deaktivieren:

int opt = -1; if (setsockopt(sock_fd, IPPROTO_TCP, TCP_NODELAY, (char *)&opt, sizeof(opt))) printf("Error disabling Nagle's algorithm.\n"); 

Jeder, der entscheidet, dass die obige Liste nicht ausreicht, und dass er sein eigenes zuverlässiges UDP entwickeln möchte, sollte sich unbedingt die Google QUIC-Spezifikation ansehen, da dies viele komplizierte Fälle und potenzielle Denial-of-Service-Angriffe umfasst. Ich habe noch nicht mit einer Implementierung davon gespielt, und vielleicht wollen oder brauchen Sie nicht alles, was es bietet, aber das Dokument ist es wert, gelesen zu werden, bevor Sie sich auf ein neues “zuverlässiges” UDP-Design einlassen.

Ein guter Startpunkt für QUIC ist hier im Chromium Blog.

Das aktuelle QUIC-Design-Dokument finden Sie hier .

Wenn Sie eine Situation haben, in der eine TCP-Verbindung möglicherweise zu langsam ist und eine UDP-Verbindung möglicherweise zu unzuverlässig ist, was verwenden Sie? Es gibt verschiedene standardmäßige zuverlässige UDP-Protokolle, welche Erfahrungen haben Sie damit?

Das Schlüsselwort in Ihrem Satz ist “potentiell”. Ich denke, dass Sie sich wirklich beweisen müssen, dass TCP in Wirklichkeit für Ihre Bedürfnisse zu langsam ist, wenn Sie Zuverlässigkeit in Ihrem Protokoll benötigen.

Wenn Sie Zuverlässigkeit von UDP erhalten möchten, werden Sie im Grunde einige TCP-functionen zusätzlich zu UDP neu implementieren, was die Dinge wahrscheinlich langsamer machen wird, als nur TCP zu verwenden.

Protokoll DCCP, standardisiert in RFC 4340 , “Datagram Congestion Control Protocol” ist möglicherweise das, was Sie suchen.

Es scheint in Linux implementiert zu sein .

Kann RFC 5405 sein , “Unicast UDP Usage Guidelines für Anwendungsentwickler” wird für Sie nützlich sein.

Haben Sie darüber nachgedacht, Ihre Daten zu komprimieren?

Wie bereits erwähnt, fehlen uns Informationen über die genaue Art Ihres Problems, aber das Komprimieren der Daten zu deren Transport könnte hilfreich sein.

RUDP . Viele Socket-Server für Spiele implementieren etwas ähnliches.

Der beste Weg, Zuverlässigkeit mit UDP zu erreichen, besteht darin, die Zuverlässigkeit im Anwendungsprogramm selbst aufzubauen (z. B. durch Hinzufügen von Bestätigungs- und Weiterübertragungsmechanismen).