Hallo,
in einer lokalen Anlage, ohne Verbindung zur Außenwelt, sollen Daten
zwischen ca. 50 Teilnehmern ausgetauscht werden. Es ist damit zu
rechnen, dass die Datenverbindungen gelegentlich so stark gestört
werden, dass einzelne Bits kippen oder über mehrere Millisekunden nur
noch Schrott ankommt.
Was spricht bei solch einer Anwendung für oder gegen UDP, bzw. für oder
gegen TCP?
Die Frage ist, ob die Daten die du verteilst, nach der Störung noch
einmal versendet werden müssten. Wenn ja, weil alle Teilnehmer alle
Daten brauchen -> TCP, wenn es nicht so schlimm ist, dass einzelne
Teilnehmer manche Pakete nicht mitbekommen (weil der Informationsgehalt
der Pakete wenn sie ein paar Sekunden zu spät eintrudeln=0 ist) dann
UDP. Wenn du uns verräts was das für Daten sind, kriegste vielleicht ne
bessere Antwort :)
ether schrieb:> Es ist damit zu> rechnen, dass die Datenverbindungen gelegentlich so stark gestört> werden, dass einzelne Bits kippen oder über mehrere Millisekunden nur> noch Schrott ankommt.
Welches Medium denn?
> Was spricht bei solch einer Anwendung für oder gegen UDP, bzw. für oder> gegen TCP?
In erster Näherung spricht nie etwas für UDP, wenn man gern möchte,
dass die Daten auch ankommen. In Umkehrung spricht entsprechend dann
alles für TCP.
Historisch bedingt hat man früher mal bei als stabil zu vermutenden
Medien (lokales Ethernet) davon Ausnahmen gemacht, um bei damaliger
langsamer Hardware höheren Durchsatz zu erreichen: NFS lief anfangs
über UDP. Hat man aber mittlerweile auch eingestampft, seit etwa
10 Jahren macht man das praktisch nur noch über TCP.
Sven schrieb:> Wenn du uns verräts was das für Daten sind, kriegste vielleicht ne> bessere Antwort :)
Danke für die Antwort. Nun, es sind ca. 100 Byte Nutzdaten, die jeder
Teilnehmer alle 50 Millisekunden erhalten soll, bzw. nach 100
Millisekunden erhalten haben muß (!). Es wird mit 100 MB/s gesendet.
> Danke für die Antwort. Nun, es sind ca. 100 Byte Nutzdaten, die jeder> Teilnehmer alle 50 Millisekunden erhalten soll, bzw. nach 100
Das ist keine Frage der Größe sondern vielmehr eine Frage um was für
Daten es sich handelt.
Wenn du beispielsweise 50 Uhren mit einem genauem Zeitsignal versorgen
willsat, wäre UDP ok. Denn ein verlohrenes Paket wird ja automatisch
durch das nächste Paket 50ms später korrigiert, bzw, der Teilnehmer auf
den aktuellen Stand gebracht.
In allen anderen Fällen wäre TCP anzuraten. Aber wie Jörg schon schrieb:
Wenn du ne pauschale Aussage willst ist TCP immer die bessere Wahl.
Man muss sich auch die Frage stellen, ob das Übertragungsmedium
vielleicht in deinem Fall nicht so optimal gewählt ist, dass es ständig
zu Störungen kommt.
Sven schrieb:> Wenn du beispielsweise 50 Uhren mit einem genauem Zeitsignal versorgen> willsat, wäre UDP ok.
Die Daten lösen schon Aktionen aus, die ohne nennenswerten Zeitverzug
von mehreren Teilnehmern "synchron" umgesetzt werden müssen.
> Man muss sich auch die Frage stellen, ob das Übertragungsmedium> vielleicht in deinem Fall nicht so optimal gewählt ist, dass es ständig> zu Störungen kommt.
Leider lassen sich nicht alle Strecken, obwohl wirklich mächtige Störer
am Werk sind, durch LWL, WLAN etc. ersetzen.
Jörg Wunsch schrieb:> In erster Näherung spricht nie etwas für UDP, wenn man gern möchte,> dass die Daten auch ankommen.
Das stimmt so pauschal nicht. Besondern dann nicht, wenn wichtiger ist,
dass die neuesten Daten auch ASAP ankommen, als dass alle Daten fein
säuberlich im Gänsemarsch verspätet ankommen.
So kann bei UDP die Wiederholung mit aktuellen Daten erfolgen, während
sich bei TCP bei anhaltenden Verzögerungen nutzloser veralteter Kram im
TCP-Layer stapelt und die Übertragung der aktuellen Version behindert.
Die häufig anzutreffende intuitive Daumenpeilung, UDP sei allenfalls
schneller, sonst aber sei TCP stets besser, ist nicht zutreffend.
Man kann auch durchaus bei UDP dafür sorgen, das die Daten sicher beim
Empfänger ankommen, indem man ein einfaches Protokoll aufsetzt, d.h. man
sendet die Daten zum Empfänger und dieser bestätigt dem Sender
(ebenfalls per UDP), das die Daten angekommen ist. Wenn die Bestätigung
ausfällt, wiederholt der Sender die Daten.
Der Entwickler schrieb:> Man kann auch durchaus bei UDP dafür sorgen, das die Daten sicher beim> Empfänger ankommen, indem man ein einfaches Protokoll aufsetzt
Die Erfahrung lehrt nur, dass dieses sich meist am Ende (wenn's also
wirklich drauf ankommt) schlechter verhält als das gut erprobte
TCP.
Der Entwickler schrieb:> Man kann auch durchaus bei UDP dafür sorgen, das die Daten sicher beim> Empfänger ankommen, indem man ein einfaches Protokoll aufsetzt, d.h. man> sendet die Daten zum Empfänger und dieser bestätigt dem Sender> (ebenfalls per UDP), das die Daten angekommen ist. Wenn die Bestätigung> ausfällt, wiederholt der Sender die Daten.
Dann kann man auch gleich TCP verwenden. Ich würde prinzipiell immer zu
TCP raten, es sei denn, die Daten sind unkritisch oder aber ein erneutes
Senden würde keinen Sinn machen, z.B. bei Echtzeitdaten wie Video oder
Audio. Als Faustregel kann man sagen, dass man UDP immer dann benutzen
kann, wenn einzelne verlorene Pakete unkritisch sind UND wenn ein
verspätetes Paket so oder so nicht mehr verarbeitet werden kann. Bei
einer Uhr würde es also z.B. keine Sinn machen nochmal zu senden, dass
es 13:00:00 ist wenn davor schon 13:00:01 erfolgreich übertragen wurde.
UDP ist unzuverlässig wie deine Übertragung. TCP kümmert sich darum das
Pakete in der richtigen Reihen folge ankommen und ggf. neu angefordert
werden. Das kann Fluch und Segen zu gleich sein. Müssen denn die Daten
in deiner Anwendung immer Übertragen werden und kann die Anwendung ohne
die Daten nicht weiter arbeiten ? Oder sollten Sie nur gelegentlich
übertragen werden und es kann zur not auch noch mit veralteten oder
keinen Daten weiter gemacht werden ? Im ersten Fall TCP im zweiten Fall
UDP.
Ein klassisches Beispiel für Fall 2 wäre Videoübertragung. Dann
ruckelt's halt im Notfall und hagelt Kompressionsartefakte, aber
hauptsache es geht irgendwie weiter.
Gruß Heiko
ether schrieb:> Nutzdaten, die jeder Teilnehmer alle 50 Millisekunden erhalten soll
Da bleibt Dir nur UDP-Broadcast (bzw. Multicast).
Stell Dir mal vor, 50 Teilnehmer haben je 49 TCP-Connections, auf denen
sie alle 50ms (also jede Millisekunde 1 Datenblock) senden sollen, und
nur einige davon sind gestört ... da geht nichts mehr, zumindest nicht
in 100ms.
UDP: 1 Paket pro 50ms
TCP: 49*1 Datenpaket+TCP-Handshake(>=1) --> >=98 Pakete pro 50ms
> bzw. nach 100 Millisekunden erhalten haben muß (!)
Mit normalem IP keine Chance, das immer zu gewährleisten.
Der Entwickler schrieb:> Man kann auch durchaus bei UDP dafür sorgen, das die Daten sicher beim> Empfänger ankommen, indem man ein einfaches Protokoll aufsetzt, d.h. man> sendet die Daten zum Empfänger und dieser bestätigt dem Sender> (ebenfalls per UDP), das die Daten angekommen ist. Wenn die Bestätigung> ausfällt, wiederholt der Sender die Daten.
Wenn eine solche Wiederholung in die Zeitvorgaben paßt, ist es doch
sinnvoller, die Daten als Broadcast grundsätzlich mehrmals zu
wiederholen (Seriennummer im Paket verhindert Doppelauswertung)
Was soll den eigentlich passieren, wenn Daten nicht ankommen?
Jörg Wunsch schrieb:> Die Erfahrung lehrt nur, dass dieses sich meist am Ende (wenn's also> wirklich drauf ankommt) schlechter verhält als das gut erprobte> TCP.
Weil es sich ja auch meist nicht um Inselsysteme handelt. UDP durchs
Internet ist allerdings in der Tat häufig Käse, da sehr oft irgendwo auf
dem Weg was verworfen wird.
Falls der OP ein 1->N Szenario hat, ist es am sinnvollsten die Daten per
UDP Broadcast eichfach mehrfach innerhalb des Zeitfensters zu
verschicken, eine Sequenznummer ins Paket einbauen und zusätzlich die
Prüfsumme einschalten.
Bei einem N->M Szenario wäre TCP angesagt, es dürfte aber bedingt durch
die Paketverwerfungen aufgrund überlasteter Ausgangspuffer und Störungen
häufiger zu Überschreitungen der Echtzeitanforderung kommen.
Dauergast schrieb:> Stell Dir mal vor, 50 Teilnehmer haben je 49 TCP-Connections, auf denen> sie alle 50ms (also jede Millisekunde 1 Datenblock) senden sollen, und> nur einige davon sind gestört ... da geht nichts mehr, zumindest nicht> in 100ms.
wo soll da das Problem sein. Wir habe doch die 386er jahre schon eine
weile hinteruns. Jeder aktuelle PC macht soetwas nebenbei. Und es wird
auch fast immer unter 100ms bleiben, nur garantieren wird es niemand.
Die Charakteristik des TCP-Retry Verfahrens ist Teil des TCP-Stacks,
nicht der Anwendung. Die Verzögerung von Retries kann dadurch grösser
sein als hier gefordert, obwohl das Netz grad frei ist, weil dynamisch
abhängig von der Historie, von der Version des Stack/Kernels, usw. Wenn
man Echtzeitbedingungen hat, wie hier, ist TCP problematisch.
A. K. schrieb:> Die Verzögerung von Retries kann also grösser sein> als hier gefordert.
Da die Übertragungswege aber hier offenbar eine nicht näher
spezifizierte Instabilität mit sich bringen, kann diese Verzögerung
ohnehin kein noch so ausgeklügeltes Verfahren garantieren, egal
ob man nun TCP nimmt oder selbst was strickt.
Wenn die Variante UDP über Broadcast/Multicast genügt, dann ist das
schön, und sicher die beste Wahl. Ansonsten bleibe ich dabei: jeder
Versuch, ein Retry-Verfahren selbst zu entwerfen (wenn denn ein
solches nötig wäre), unterliegt einer sehr hohen Wahrscheinlichkeit,
viele der Fehler zu wiederholen, die in den Netzwerk-Stacks der
letzten 20 Jahre alle bereits überwunden worden sind.
Was nicht rechtzeitig über das Medium rübergekommen ist, wird auch
ein noch so ausgeklügeltes Retry-Verfahren jedoch nicht termingerecht
abliefern können.
Das Hauptproblem ist ja das der client nicht wissen kann das ein packet
für ihn verloren gegangen ist. Wenn der Server aller 50ms ein Packet
abschickt, dann kann der client erst nach 100ms feststellen das ein
packet fehlt. (bei den kurzen zeit fragt der Stack noch nich nach wo die
quittung bleibt)
Peter II schrieb:> bei den kurzen zeit fragt der Stack noch nich nach wo die> quittung bleibt
Das muss nicht stimmen. Schau' dir mal den Algorithmus für die
Berechnung der Retry-Zeit an, ist auch im Wikipedia ganz passabel
erläutert. Der hängt insbesondere von der gemessenen RTT ab. Wenn
diese kurz ist (bei einem 100-Mbit/s-Medium liegt sie typisch gut
unter 1 ms), dann müsste auch der retransmission timeout im Bereich
weniger Millisekunden liegen.
Wenn die RTT im Bereich einiger 10 ms rauskommt, ist die ganze
Aufgabenstellung hingegen ziemlich sinnlos.
Ich habe kürzlich ein System implementiert, das auf UDP aufsetzt und
dann als nächste Schicht ein eigenentwickeltes Protokoll verwendet, das
für eine gewisse Datensicherheit sorgen soll.
Das sah bei der Konzept erstellung noch alles sehr einfach und
überschaubar aus, aber nach hat sich herausgestellt, daß man doch
ettliche Fälle hatte, die im Konzept nicht berücksichtig worden waren.
Das eigene Protokoll bläht sich immer weiter auf und das Ende vom Lied
war: hätten wir doch besser gleich TCP genommen.
Jörg Wunsch schrieb:> Wenn die RTT im Bereich einiger 10 ms rauskommt, ist die ganze> Aufgabenstellung hingegen ziemlich sinnlos.
Und genau in die Richtung wird es gehen (Formel aus en. Wikipedia):
RTT = (α · Old_RTT) + ((1 − α) · New_Round_Trip_Sample) mit 0 <= α < 1.
Bei einem Netz was häufig Ausfälle hat und zusätzlich mehrere Stationen
gleichzeitig bedienen muss, wird die RTT stark ansteigen.
Allerdings gab es da noch Algorithmen die nur die RTT von Paketen
beachtet, die nicht wiederholt gesendet werden mussten...
Jörg Wunsch schrieb:> Da die Übertragungswege aber hier offenbar eine nicht näher> spezifizierte Instabilität mit sich bringen, kann diese Verzögerung> ohnehin kein noch so ausgeklügeltes Verfahren garantieren, egal> ob man nun TCP nimmt oder selbst was strickt.
Selbstverständlich kann sie das nicht. Das kann man mit garnichts.
Aber mit TCP hat man keine Ahnung, wie die Retries arbeiten, weil das
auf einer nicht von der Anwendung kontrollierten Ebene stattfindet.
Dazu kriegt man dann noch ein Problem mit halb offenen Verbindungen und
hängenden Sockets, weil die TCP-Close Prozedur klemmen kann und man
einige Minuten Timeout am Hals haben kann.
Nope, in diesem Zeitrahmen geht nur UDP, weil man volle Kontrolle über
das Zeitverhalten und den wahrgenommenen Verbindungsstatus haben muss.
Peter II schrieb:> wo soll da das Problem sein. Wir habe doch die 386er jahre schon eine> weile hinteruns. Jeder aktuelle PC macht soetwas nebenbei. Und es wird> auch fast immer unter 100ms bleiben, nur garantieren wird es niemand.
Das Problem ist das der TE mal wieder nur stückchenweise mit Infos
rausrückt, ob das ganze auf nem 8 Bitter oder nem Arm7 Board laufen soll
wissen wir nicht.
Klar läuft TCP auf nem Atmega aber ob sich damit sinnvoll Echtzeitdaten
austauschen lassen ist die andere Frage.
Dauergast schrieb:> Mit normalem IP keine Chance, das immer zu gewährleisten.
Jein, 2 dedizierte Medien über die per udp alles doppelt gesendet wird
sollte reichen.