# UDP mit Sequenznummern?



## Verjigorm (14. Apr 2007)

Ich habe da ne kleine Applikation, die DatagramPackets für die Kommunikation benutzt.
Irgendwie gehen da wohl irgendwo Pakete verloren. Nun wollt ich sowas wie ne Sequenznummer einbauen.
Muss ich diese Sequenznummer in den Datenteil packen und selbst rausfiltern oder gibts dafür ne vorgesehene Funktion? ich hab bisher nix gefunden.

Und wie is das dann :
Der Empfänger bekommt Paket 4712 und merkt nun, dass das Paket 4711 verlorengegangen ist.
Nun müsste ich ja das verlorene Paket beim Sender nochmal anfordern.
Da aber mittlerweile schon weitere Pakete angekommen/verschickt worden sind, muss der Sender ne gewisse Paketzahl zwischenspeichern um das verlorene Paket nochmal senden zu können, und der Empfänger muss dann erstmal mit der Verarbeitung warten, bis das fehlende Paket nochmal gesendet wurde? seh ich das richtig?
(nein ich will kein TCP/IP benutzen  )

edit: zur synchronisation noch ne Frage:
was ist denn als "synchronisationgeschwindigkeit" so zu empfehlen?
bei mir ändert sich teilweise im 10ms Takt etwas
muss ich da jede Änderung auch "live" übertragen oder wird das zu aufwendig? 

mfg Verjigorm


----------



## HoaX (14. Apr 2007)

nur weil du nach 4010 gleich 4712 empfängst bedeutet das nicht dass 4711 verlorengegangen ist. die empfangsreihenfolge dann durchaus von der beim versenden abweichen.

wenn du die pakete in der festen reihenfolge brauchst ohne dass eines verloren geht dann nimm tcp.
wieso magst du tcp nicht?

udp würde ich nur verwenden wenn auch mal auf ein paket verzichtet werden kann, z.B. voip, u.U. bei spielen, ...

das musst du wissen ob so schnelle updates nötig sind oder ob du die erstmal puffern kannst, hängt immer vom anwendungsfall ab.


----------



## Verjigorm (14. Apr 2007)

ich habs nun ohne tcp angefangen und wills auch so fertig machen


----------



## HoaX (14. Apr 2007)

musst doch nur den socket austauschen ... wenn du dir wirklich all das wirklich nachprogrammieren willst: viel spaß, das packst du nicht


----------



## Gast (16. Apr 2007)

Das was Du da mit Sequenznummern vorhast, ist doch exakt das, wo der Unterschied zwischen UDP und TCP liegt.

Wenn Du es dennoch nachbauen willst, steht das in Wikipedia ganz gut beschrieben.
TCP, OSI-Schichtmodell
sind da ganz gute Suchworte.


----------



## schalentier (16. Apr 2007)

Na nee, es gibt noch mehr Unterschiede zwischen TCP/IP und UDP, als die Garantien (alle Bytes kommen an, alle Bytes kommen in der richtigen Reihenfolge an, jedes gesendete Byte kommt genau einmal an). Und nur Socket austauschen reicht auch nicht. 

TCP ist verbindungsorientiert, UDP nicht (man kann einfach UDP Packete an eine Adresse schicken, muss also vorher keine Verbindung aufbauen --> effizienter, wenn viele Clients an einem Server haengen, oder bei Peer2Peer). 

Bei TCP werden Streams uebertragen, bei UDP Packete. 

Zudem kann man bei TCP nicht einstellen, was genau in Fehlenfaellen passieren soll. Fallen ein paar Bytes aus (und kommen auch nicht spaeter an), so bricht die ganze Verbindung ab (Timeout). Das ist nervig, wenn man mit ein paar verlorenen Packeten leben kann. 

Bei UDP gibts nichts vorgeschriebenes, was die Sequenznummern angeht. Aber so wie du es beschrieben hast, wird es ueblicherweise gemacht. UDP ist schnell und billig. Du kannst also einfach mal probieren, wie schnell du Packete raushauen kannst. 

Sinnvoll waere es moeglicherweise, die rausgehenden Packete zu sammeln und erst ab einer gewissen Groesse (paar kb's) oder nach einer maximalen Zeit als Gesamtpacket zu schicken. 

Tja, aber das haengt halt extrem von der Anwendung ab. Z.b. bei Spielen sendet man meist nur die relativen Aenderungen zwischen 2 Zeitpunkten und nur ab und an mal die absoluten Positionen. Faellt also mal ein Packet weg, kann es sein, dass die Clients unterschiedliches "sehen", aber nach einer (kurzen) Zeit sollte alles wieder synchronisiert sein.


----------



## HoaX (16. Apr 2007)

wenn er ein paar kbs puffert und auf einmal sendet ist die warscheinlichkeit dass diese in falscher reihenfolge imo höher als wenn er sie direkt sendet.

auch bei tcp können pakete verloren gehn, die werden halt neu angefordert, wenn wirklich jedesmal die selben pakete verschwinden is das nichtmehr "ein paar verlorene pakete".

aber wie gesagt, wenn ich wirklich alle pakete in richtiger reihenfolge brauche: tcp
wenn reihenfolge und vollständigkeit nicht so wichtig sind: udp
der mehraufwand selbst sowas in udp zu machen wäre mir zu groß

wenn socket austauschen + paar kleine änderungen nicht reicht ist imo das design der anwendung nicht gut


----------



## schalentier (17. Apr 2007)

HoaX hat gesagt.:
			
		

> wenn socket austauschen + paar kleine änderungen nicht reicht ist imo das design der anwendung nicht gut



Ich glaub wir reden etwas aneinander vorbei. Natuerlich, wenn man sich entsprechende Wrapper baut, die TCP und UDP Kommunikation wegkapseln, sollte eine kleine Aenderung (Einstellung) reichen, um zwischen beiden Protokollen hinundher zu switchen. 

Allerdings muss man dann fuer UDP alles nachprogrammieren, was TCP schon kann. Damit wird man wohl keinen Erfolg haben... (rein geschwindigkeitstechnisch).

Aber es gibt eben auch Faelle, wo TCP nicht eingesetzt werden kann. Weil es zu langsam ist, weil es pro Client eine Verbindung braucht, usw. 

Wenn man sich dann also fuer UDP entscheidet, muss man die gesamte Anwendung darauf auslegen. Irgendwo muessen fehlerhafte Packete dann "aufgeloest" werden. Und zwar nicht nur, indem man die einfach neu anfordert, sondern indem man in der Anwendungslogik Mechanismen einbaut, die diese Problemfaelle irgendwie geschickt abfangen. Man kann ja nicht sagen, UDP ist nur fuer Anwendungen, wo es egal ist, wenn ein paar Netzwerkpackete fehlen. Das ist wohl niemals egal. Aber man kann seine Anwendung so bauen, dass sie stabil auf potentielle Fehler reagiert und trotzdem noch laeuft. 

Mehr Infos gibts, wenn man bei google nach "raknet" sucht. Das ist eine C++ Library fuer Netzwerkkommunikation (UDP).


----------



## NTB (17. Apr 2007)

Wenn es bei Deiner Anwendung um ein Spiel geht, kann ich Dir glaube ich ein ganz nettes Buch empfehlen, dass Mechaniken zu dem Problem des Packet Loss beschreibt. 
Interpolation und Extrapolation etc...


----------



## schalentier (17. Apr 2007)

Und? Wie heisst das Buch? Taet mich auch interessieren ;-)


----------



## Sanix (17. Apr 2007)

Gerade eine andere Frage dazu. Ich habe ein Spiel mit 4 Clients und einem Server.
Das Prinzip ist folgendes:
Ich drücke eine Taste,  die Aktion wird zum Server gesendet und der macht einen Broadcast an alle Clients. Nun führen alle Clients die Aktion aus (Bsp. Spieler3.moveLeft()).
Dies sollte eigentlich funktionieren, nur gibt es ein Problem: Die Verzögerung.
Nehmen wir an, der Weg vom Client1 zum Server dauert 100ms, der Weg vom Client2 zum Server dauert 200ms. Somit wird das Ganze mit der Zeit asynchron.
Einen möglichen Lösungsansatz könnte ich mir so vorstellen:
Am Anfang wird ein Zeitwert ausgetauscht. Nun wird die Aktion immer relativ zu dieser Zeit ausgeführt, also verzögert.
Bsp.:
Client 1 will moveLeft ausführen:
aktuelleZeit + Verzögerungszeit|moveLeft wird gesendet. Nun sollten alle Clients hinter dieser Zeit liegen und erst zu dieser Zeit den Befehl ausführen. Aber wie das dann genau funktionieren soll weiss ich auch nicht, da der Spieler ja jetzt seine Figur bewegen will und nicht erst in 500ms.


----------



## schalentier (18. Apr 2007)

Tjo, der Lag... ist kompliziert.

Wie man mit dem umgeht, haengt ganz stark von der Anwendung ab. Zb. bei Shootern wird das oftmals so gemacht, wie du es beschrieben hast (Spiel mal einen Shooter mit 500ms Ping... beim Abdruecken dauerts die halbe Sekunde). Bei WoW zB, wird jede Interaktion am Server berechnet und nur das Ergebnis zu den Clients geschickt. Renn da mal mit nem Kumpel, der neben dir sitzt (auf ner LAN), nebeneinander los - und zwar zum gleichen Zeitpunkt. Du wirst sehen, bei dir rennt dein Avatar vorn, bei deinem Kumpel ist sein Avatar vor dir. Das ganze laeuft also immer asynchron, was aber bei WoW egal ist... in der Tat ist das ganze extrem kompliziert, besonders wenn der Lag gross wird (ab vielleicht 500ms).  

Wirklich helfen kann ich dir also nicht... am besten du probierst verschiedene Ansaetze mal aus. Bei Bewegungsablaeufen kann man evtl. ne Menge erreichen, wenn man geschickt zwischen 2 Zeitpunkten interpoliert und dabei den Lag irgendwie mit in die Rechnung einbezieht. 

Literatur darueber taet mich aber ernsthaft interessieren, @NTB...


----------

