Hallo zusammen, ich habe mal die ein oder andere Frage zur Datenübertragung mit TCP und UDP. Und zwar möchte ich mir von einem Server zyklisch Daten in einem Intervall von z.B. 20 ms zuschicken lassen. Der Client soll in einer Art Spielumgebung laufen. Bei Start der Berechnung eines neuen Frames, sollen aktuelle Daten vom Server anliegen. Nach der Berechnung sollen ebenfalls Daten an den Server zurückgeschrieben werden. Danach wird das Bild gerendert und der Zyklus startet von vorn. Jetzt könnte der Client dem Server bei Start des Spiels sagen, er solle die Daten im 10 ms Zyklus schicken damit diese auf jeden Fall bei jedem Frame aktuell sind. Damit es nicht zu Verzögerungen kommt, will ich nicht bei jedem Zyklus eine Anfrage schicken und dann auf Antwort warten. Jetzt frage ich mich: wenn der Client nur alle 20 ms abruft, sind dann zwei Datensätze im Puffer? Oder bekommt der Server erst eine Bestätigung dass die Daten angekommen sind, wenn der Client die Daten ausliest? Und wie sieht das bei UDP aus: Könnte der Server sozusagen mit "Vollgas" senden, und der Client fischt sich immer das letzte Paket aus dem Puffer? Gruß Thomas
Thomas schrieb: > Jetzt frage ich mich: wenn der Client nur alle 20 ms abruft, sind dann > zwei Datensätze im Puffer? Zunächst ja. > Oder bekommt der Server erst eine Bestätigung dass die Daten angekommen > sind, wenn der Client die Daten ausliest? Auch. Irgenwann sind halt alle beteiligten Puffer voll. > Und wie sieht das bei UDP aus: Könnte der Server sozusagen mit "Vollgas" > senden, und der Client fischt sich immer das letzte Paket aus dem > Puffer? Auch da gibt es Puffer. Zunächst muss dir klar werden, dass TCP in solchen isochronen Übertragungen nicht erste Wahl ist. TCP überträgt gnadenlos in der richtigen Reihenfolge. Auch wenn der Inhalt veraltet ist und niemanden mehr interessiert. Weshalb TCP beispielsweise bei Sprachübertragung (VoIP) nicht sinnvoll ist. Wenn wie hier immer nur der letzte Stand interessiert, dann ist die Basis UDP (oder eines der exotischeren anderen Protokolle). Ein sinnvoller Ablauf kann sein, dass der Sender alle 10ms seinen Frame sendet und beim Empfänger ein Thread nur dafür zuständig ist, den letzten Frame in einen von zwei alternierenden Puffern im RAM zu schreiben. Dann ist im RAM immer der letzte Frame vorrätig - Übertragungsfehler inklusive. Wenn das eigentliche Programm auf Empfängerseite nicht mitkommt, dann tut das nichts zu Sache, dann wird halt mal ein empfangener Frame ignoriert.
UDP bedeutet schlicht das keine Garantie übernommen wird, das einmal gesendete Daten auch ankommen. Wenn was gesendet wird, aber nicht ankommt, dann ist das so. Wird z.B. bei Streaming verwendet. Bei TCP läuft das so, dass ein Paket, das nicht beim Empfänger ankommt, vom Empfänger neu angefragt wird. Was du wie, wann, wo mit den Daten machst, ist ja deine Sache. Ob du da nun das letze oder erste oder 12503 Paket aus irgend einem Puffer holst, is ja dein Ding. Grüße
PS: Mit "Frame" dürfte in diesem Kontext ein komplettes Bild gemeint sein, oder? Ist etwas missverständlich, weil Ethernet-Pakete ebenfalls als Frames bezeichnet werden.
Ja, mit Frame ist in diesem Fall ein Bild gemeint. Ich hatte über UDP mit Prüfsumme und einer Sequenznummer die in jedem Telegramm erhöht wird auch schon nachgedacht. Es wird dann im Client nur das Datenpaket mit der höchsten Nummer ausgewertet. Ältere Pakete oder welche mit einem Prüfsummenfehler werden schlicht verworfen. Ich schreib nochmal genauer was ich vorhabe: Das ist kein Spiel im eigentlichen sinne, sondern es wird das Unreal Development Kit (UDK) eine zur Simulation einer Maschine benutzt. Die Steuerung dieser Maschine übernimmt eine SPS. Ich habe das Prinzip schon laufen, nur ist es momentan so, dass aus dem UDK über eine dll lokal auf dem Rechner mit der SPS kommuniziert wird. Das will ich jetzt auf Netzwerk ändern, weil fürs UDK ein PC mit guter Grafikkarte benötigt wird, und damit man das System relativ einfach an diverse andere Steuerungen oder auch Microcontroller anbinden kann. Darum sollte gewährleistet sein, dass auf jeden Fall zu jedem Bild-Frame die Daten aus der Steuerung aktuell vorliegen. Wie groß ist denn der interne Datenpuffer? Ich würde mal schätzen dass ein Datenpaket im Höchstfall (1000 Variablen) bis zu 50 kByte groß werden kann.
Thomas schrieb: > Wie groß ist denn der interne Datenpuffer? Wenn du das wissen musst, dann hast du schon verloren. Das ist weder klar definiert, noch ist es auf dem gleichen System stets gleich.
A. K. schrieb: > Wenn du das wissen musst, dann hast du schon verloren. Das ist weder > klar definiert, noch ist es auf dem gleichen System stets gleich. "Muss" nicht. Aber für eine Abschätzung ob es bei einem Client-Zyklus mit 20 ms sinnvoll ist, alle 1 ms Daten zu schicken. Ich habe damit so gut wie keine Erfahrung. Ich stelle mir nur vor, der Puffer ist voll und dann ist das letzte Paket nur noch halb vorhanden. Na gut, dann wird eben das Paket davor verwendet. Wichtig ist nur dass so ein Paket auf jeden Fall komplett in den Puffer passt.
Thomas schrieb: > "Muss" nicht. Aber für eine Abschätzung ob es bei einem Client-Zyklus > mit 20 ms sinnvoll ist, alle 1 ms Daten zu schicken. Wie ich schon schrieb: Wenn du Puffer brauchst, dann mach dir welche. Selber. Schreib einen Thread, der nix anderes tut als Daten zu empfangen und ins RAM zu legen. In wieviele Kilo-, Mega- oder Gigabytes auch immer. > Ich habe damit so gut wie keine Erfahrung. Ich stelle mir nur vor, der > Puffer ist voll und dann ist das letzte Paket nur noch halb vorhanden. Deshalb hatte ich vorhin alternierende Bildspeicher vorgeschlagen. Einer ist voll, der andere wird grad eben oder demnächst gefüllt und ist daher in undefiniertem Zustand. Halbe Ethernet-Frames gibts aber nicht. Die gibts nur ganz oder garnicht.
:
Bearbeitet durch User
Thomas schrieb: > "Muss" nicht. Aber für eine Abschätzung ob es bei einem Client-Zyklus > mit 20 ms sinnvoll ist, alle 1 ms Daten zu schicken. Was definitiv nicht sinnvoll ist: Mehr Daten zu schicken als der Empfänger aus dem Network-Stack abholt, in der Hoffnung, dass dabei zufällig genau jene Daten ankommen, die du haben willst. Also: Bau das so, dass dein Empfängerprogramm alle Daten kriegt, die der Sender schickt. Wenn du dann welche verwerfen willst, dann tu es selbst. Nur dann hast du Kontrolle darüber, welche das sind.
A. K. schrieb: > Deshalb hatte ich vorhin alternierende Bildspeicher vorgeschlagen. Einer > ist voll, der andere wird grad eben oder demnächst gefüllt und ist daher > in undefiniertem Zustand. Das ist schonmal eine gute Idee. Wenn aus irgendeinem Grund das Netzwerk mal kurzzeitig haken sollte, dann hat das auch keine Auswirkungen auf das Spiel. Generell scheint UDP für diesen Anwendungsfall also geeigneter zu sein. Nur werde ich dann quasi als Befehlskanal noch eine zweite Verbindung über TCP aufbauen müssen, denn diese Daten sollten schon auf jeden Fall ankommen. Und Daten vom Client an den Server sollten auch definitiv ankommen, falls z.B. ein Gegenstand vor einer Lichtschranke nur für ein Bild-Frame steht.
Thomas schrieb: > Nur werde ich dann quasi als Befehlskanal noch eine zweite Verbindung > über TCP aufbauen müssen, denn diese Daten sollten schon auf jeden Fall > ankommen. Und - O Wunder! - genau so arbeiten VoIP und Videotelefonie. SIP oder H323 per TCP für die Steuerung und RTP per UDP für Sprach/Video-Stream.
Thomas schrieb: > Generell scheint UDP für diesen Anwendungsfall also geeigneter zu sein. > Nur werde ich dann quasi als Befehlskanal noch eine zweite Verbindung > über TCP aufbauen müssen, denn diese Daten sollten schon auf jeden Fall > ankommen. > Und Daten vom Client an den Server sollten auch definitiv ankommen, > falls z.B. ein Gegenstand vor einer Lichtschranke nur für ein Bild-Frame > steht. Du mußt dir halt im Klaren darüber sein, daß bei Paketverlust dieses Paket natürlich dann verzögert ankommt, nachdem es eben nochmal angefordert und erneut gesendet wurde, und daß sämtliche Pakete, die danach gesendet werden, so lange verzögert werden, bis das fehlende Paket nachgeliefert wurde. Die sind dann evt. zwar schon am Emfängerrechner angekommen, werden aber von dessen IP-Stack zurückgehalten.
Rolf Magnus schrieb: > daß bei Paketverlust TCP ist Streamorientiert, UPD Paketorientiert, daher kriegt man auf Anwendungsschicht eh nix von Paketen mit, da muss man sich selber drum bemühen Pakete zu erkennen, das sollte man auch im Hinterkopf behalten.
Wenn man nur UDP braucht ist der GPLV2 Stack, den es mit/bei FreeRTOS gibt, sicher auch mal einen Blick wert. Hat jemand damit schon Erfahrungen? http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/FreeRTOS_Plus_UDP.shtml
Jürgen Liegner schrieb: > Wenn man nur UDP braucht ist der GPLV2 Stack, den es mit/bei FreeRTOS > gibt, sicher auch mal einen Blick wert. Gehts hier nicht um "PC-Programmierung", Spiele(-Server) usw? Ich denk mal, jedes dafür in Frage kommende Betriebsystem wird schon einen UDP-Stack integriert haben.
Ich hab mal nachgesehen wie das beim in der Industrie eingesetzten Profinet IO gemacht wird. Das setzt zwar direkt auf der MAC Ebene auf, aber ist demnach wie auch UDP paketorientiert. Dort gibt es ein festes Aktualisierungsraster z.B. einer Ausgabebaugruppe von 1 ms. Der Teilnehmer akzeptiert bis zu drei Aktualisierungszyklen ohne Daten erhalten zu haben, danach geht er in Fehlerzustand und setzt seine Ausgänge in einen sicheren Zustand. Daraus folgt, dass bei Profinet einzelne Datenpakete unter Umständen einfach unter den Tisch fallen. Obwohl ich das schon eingesetzt habe war mir das bisher gar nicht klar. So würde meine UDP-Lösung dann (bis auf den Fehlerzustand) auch funktionieren. Bei Profibus (auch wenn das mit Profinet nicht unbedingt vergleichbar ist, Token-Passing vs. CSMA) war das anders. Dort gab es ein Retry Limit was im Normalfall in einem Netz ohne Repeater oder Ringstrukturen auf 1 steht. D.h. ein Telegramm wird auf jeden Fall zugestellt. Wenn nicht, dann geht der Teilnehmer auf Fehler.
Es läuft letztlich auf die Frage hinaus, ob man im Steuerkanal mit den Nebeneffekten von TCP leben kann, oder auf Basis von IP oder UDP einen eigenes der Anwendung angepasstes Protokoll zur Sicherstellung der Übertragung kritischer Informationen drauf setzt. Man vergisst angesichts der Dominanz von TCP und UDP leicht, dass es daneben noch einen ziemlichen Rattenschwanz anderer Transport Layer Protokolle gibt. Man ist mit solchen Problemen selten der Erste. Nur kann man nicht unbedingt drauf wetten, dass die im TCP/IP Stack schon implementiert sind.
Anmerkung zur Paketgröße von Udp als auch Tcp-Paketen: ohne besondere Optionen sind nur max. 1.5kByte Pakete zu empfangen und zu senden. Zusätzlich ist der bereits erwähnte Umstand zu beachten dein Betriebssystem (bzw sein Stack) packt seine Ethernetdaten direkt hintereinander in seinen Puffer so das es nicht ohne weitere Codierung/Makierung der Daten möglich ist diese einzelnen Paketen zuzuweisen!
Trundle Trollkönig schrieb: > Anmerkung zur Paketgröße von Udp als auch Tcp-Paketen: ohne besondere > Optionen sind nur max. 1.5kByte Pakete zu empfangen und zu senden. Das ist Sache des Network Layers (Ethernet). In TCP hat man es mit einem Stream zu tun, daher ist die Paketgrösse wenig relevant. In IP sind Pakete möglich, die grösser als ein Ethernet Frame sind, somit gilt das auch für UDP. Weil sie ggf. fragmentiert werden. > Betriebssystem (bzw sein Stack) packt seine Ethernetdaten direkt > hintereinander in seinen Puffer so das es nicht ohne weitere > Codierung/Makierung der Daten möglich ist diese einzelnen Paketen > zuzuweisen! Das gilt für TCP. UDP Pakete bleiben erhalten.
:
Bearbeitet durch User
ich hatte das vom TO so verstanden, das er immer ein Paket, verpackt in nur einem Ethernetpaket (1 Frame = 1 Ethernetpaket zumindest kenn ich das so), mit gleicher Payloaddatenstruktur, alle was weiß ich wieviel ms versenden möchte und davon die aktuellsten Daten dann weiterverarbeiten möchte. Dazu wäre es nötig die nicht mehr erkenntlich Paketstruktur im tcp-stack, falls er Tcp-Protokoll verwendet, durch selbst implementierte Markierungen des Payloads wieder herzustellen. Und wenn es nur 1 Ethernetpaket sein soll ist er nunmal an die maximale Ethernetpaketgröße gebunden. Aber ich glaube mit vlan-tag kann man auch mehr als 1.5k verschicken.
:
Bearbeitet durch User
Habe ich das richtig verstanden? 1.2 ... 1.3 Der Client sendet die Zustände der Ausgänge mit einem Zeitstempel an den PC. 2.1 Der Server, PC, berechnet anhand der empfangenen Zustände der Ausgänge die neuen Zustände der Eingänge und schickt das Ergebnis an den Client zurück. 2.2 Nebenbei wird mittels dem UDK ein Spiel (Anlage) ausgeführt, das auf dem PC-Monitor dargestellt wird. 1.1 Der Client empfängt die neuen Zustände der Eingänge. 1.2 Der Client bzw. die SPS arbeitet den nächsten Zyklus ab. 1.3 Der Client sendet die Zustände der Ausgänge mit einem Zeitstempel an den PC. 2.1 ...
Trundle Trollkönig schrieb: > Ethernetpaket (1 Frame = 1 Ethernetpaket zumindest kenn ich das so), Das wurde bereits oben geklärt, sein "Frame" hat nichts mit Ethernet zu tun: Beitrag "Re: Fragen zur Datenübertragung mit TCP oder UDP"
:
Bearbeitet durch User
Hi, damit man sich mal was darunter vorstellen kann, gibts hier es ein Video was mit der bisherigen Version (Kommunikation lokal) umgesetzt wurde: http://www.youtube.com/watch?v=KzuPgLJ88UU Das "Spiel" (Simulation ist der passendere Ausdruck) bildet sozusagen die Realität ab. Die roten Linien stellen Lichtschranken dar, die SPS steuert in dem Fall einfach ein paar Motoren an. @mar IO: Beide Programme sind in keiner Weise synchronisiert. Der Zyklus der Simulation sieht so aus: 1. Simulation liest die Befehle aus der SPS (z.B. Motor an oder aus) 2. Berechnung der Physik 3. Zurückschreiben vom Signalen an die SPS (z.B. Lichtschranke belegt) 4. Rendern des Bildes Die SPS hat im Normalfall ebenfalls eine zyklischen oder freilaufenden Task. Liest die Eingänge ein (z.B. Lichtschranke belegt) und startet daraufhin einen Motor. Bezüglich UDP schreibe ich mir erstmal ein kleines Testprogramm um zu sehen wie sich die Kommunikation da überhaupt verhält. Bezüglich Paketgröße findet man widersprüchliche Angaben im Netz. Wenn die Daten über eine DSL Leitung gehen wird ja auf jeden Fall auf MTU Größe fragmentiert. Aber im LAN dürfte das doch nicht der Fall sein.
Thomas schrieb: > Bezüglich UDP schreibe ich mir erstmal ein kleines Testprogramm um zu > sehen wie sich die Kommunikation da überhaupt verhält. Bezüglich > Paketgröße findet man widersprüchliche Angaben im Netz. Wenn die Daten > über eine DSL Leitung gehen wird ja auf jeden Fall auf MTU Größe > fragmentiert. Aber im LAN dürfte das doch nicht der Fall sein. Es gibt immer eine MTU. Im Ethernet ist die 1500, beim DSL leicht darunter. Das bedeutet aber nicht, dass UDP Pakete darauf limitiert sein müssen. Allerdings müssen IPv4-Stacks nicht mehr als 576 Bytes reassemblieren können, wobei dieser Wert aber allenfalls bei Zwergsystemen zu finden ist, nicht bei PCs.
:
Bearbeitet durch User
Thomas schrieb: > Wenn die Daten > über eine DSL Leitung gehen wird ja auf jeden Fall auf MTU Größe > fragmentiert. Aber im LAN dürfte das doch nicht der Fall sein. Bei Ethernet gibt es eine maximale Paketgröße. Mittels Jumbo-Frames kann man das im lokalen Netz noch steigern. Das ist nützliche wenn man große Menge an Daten über Netzwerk verschiebt, da man mehr Nutzdaten pro Sekunde übertragen kann. Im allgemeinen Interessiert die MTU nicht, da der UDP-Stack selber seine Pakete entsprechend aufteilt.
mar IO schrieb: > Mittels Jumbo-Frames kann > man das im lokalen Netz noch steigern. Im Prinzip ist das zwar richtig, es wird hier jedoch eher zur Verwirrung beitragen, als ihm wirklich helfen. So lange man noch mit normalem Ethernet und TCP/IP kämpft, sollte man von Jumbo Frames die Finger lassen. Danach besser auch.
:
Bearbeitet durch User
Mit einem Python UDP Socket bekomme ich bis zu 65515 Bytes mit einem sendto() geschickt. In der Wireshark-Anzeige sieht man dann gesplittete Einzelpakete zu je max. 1480 Bytes, angezeigt als "Fragmented IP protocol". Das Zerlegen und zusammensetzen scheint also auf IP Layer abzulaufen. Sieht doch eigentlich zuverlässig aus, die Datenmenge reicht mir dicke aus.
Thomas schrieb: > Sieht doch eigentlich zuverlässig aus, die Datenmenge reicht mir dicke > aus. 'Zuverlässig' ist es eben bei UDP nicht. Wenn ein Frame kaputt ist ist das ganze datagram weg. Kann im LAN funktionieren, muss aber nicht. Wenn du über DSL/WAN übertragen willst musst du unterhalb der MTU bleiben. /uli
U.Hertlein schrieb: > Wenn du über DSL/WAN übertragen willst musst du unterhalb der MTU > bleiben. Weshalb?
A. K. schrieb: > U.Hertlein schrieb: >> Wenn du über DSL/WAN übertragen willst musst du unterhalb der MTU >> bleiben. > > Weshalb? Das würde mich auch interessieren, denn im allgemeinen interessiert die MTU nicht und vor allem in diesem Fall!
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.