# DatagramSocket rausfinden ob recive möglich ohne zu blocken



## Empire Phoenix (30. Okt 2009)

Gibt es eine Möglichkeit wie ich rausfinden kann, ob ein DatagramSocket in der Lage ist recive aufzuraufen ohne zu blocken? 

Weil ich bin gerade dabei für ein Spiel eine simple Netzwerkverbindung zu schreiben, und es ist etwas dumm wenn ich einen eigenen Thread habe der nur darauf wartet (zudem muss ich dann alles Threadsafe schreiben, sonst wenn dass über eine Update methode schreibe, die einfach vom Main Thread aufgerufen wird kann  ich mir das sparen)


----------



## tuxedo (2. Nov 2009)

Nimm TCP. Das ist dafür schnell genug...

Mal davon abgesehen: Non-Blocking Datagram-Sockets gibts (noch) nicht. Dafür aber non-blocking Sockets (Java NIO: xSocket, Netty, Mina, ...)

- Alex


----------



## Empire Phoenix (4. Nov 2009)

Das einem alle hier immer Tcp für spiele andrehen wollen 

Naja habe es jetzt mit einem eigenen Thread nur fürs recive und einem Stack für von diesem gelesene Packete eingebaut, somit kann ich jetzt inner Update() den Stack abfragen ob isEmpty()  sollte denke ich keine Probleme verursachen, weil Stacks ja von Vector erben, und somit immer Synchron sein sollten oder?


----------



## tuxedo (5. Nov 2009)

Tja, ist halt so. Viele großen Spiele arbeiten mit TCP. Bei den wenigsten ergibt UDP einen Sinn. Mit Sinn meine ich: Senden von Paketen bei denen es egal ist ob und in welcher Reihenfolge sie ankommen.

Wenn das erfolgreiche zustellen eines Pakets wichtig ist und/oder die Reihenfolge der Pakete eine Rolle spielt, dann ist es quatsch UDP zu nehmen und das zugesicherte Zustellen sowie die Reihenfolge in ein Protokoll, aufbauen auf UDP zu gießen. 

Denn genau das macht TCP schon. 

Spontan fällt mir gar kein Spiel ein in dem Zustellung und Reihenfolge keine Rolle spielt. Nehmen wir ein MMORPG. wie World of Warcraft. Wenn du da nem Monster eins auf die Rübe haust und das Paket kommt nicht an: Super. "Sterben musst du sowieso. Schneller geht's mit UDP". 

Oder eine Rennsimulation: Wenn da das "anstupsen" anderer Wagen unter den Tisch fällt: Naja, "legales schummeln?"

Oder eine Wirschaft-Simulation: Du baust eine Lagerhalle, oder im Fall von UDP eventuell auch nicht.

Du siehst worauf ich hinaus will? Überall sollte man zumindest sicherstellen dass das Paket überhaupt ankommt. TCP macht das schon von Haus aus ohne extra zutun. 

Bei einer Audioübertragung ist es relativ wurscht ob da das eine oder andere Audiopaket "abhanden" kommt oder in der falschen Reihenfolge ankommt. Die Pakete stellen einen so kurzen Abschnitt des Audiosignals dar, dass das fehlen eines Pakets oder die falsche Reihenfolge nicht so sehr eine Rolle spielen. Natürlich gibts auch hier protokolle die die Reihenfolge sicherstellen. Aber mit Paketverlust in akzeptablen Maß kann jede Sprachübertragung leben. Und hier zahlen sich mit UDP auch die geringeren Transportkosten aus. Weniger Overhead -> schnellere Übertragung.

- Alex


----------



## Empire Phoenix (9. Nov 2009)

Ähnlich siht es allerdinga uch bei einem 3dShooter aus, kein einizger der bekannten benutzt TCp, warum? Weil falls ein Packet icht akommt ist das nächste bei tickraten um 66 eh schon unterwegs, hier würde ein kurzes stocken erheblich nerven, ausserdem möchte ich auf dieses hier verweisen.

Das Problem mit TCp ist hier nämlich das verhalten bei stockender Verbindung Date kurzzeitig langsamer zu senden oder komplett auszusetzten und dann die Verbindung neu aufzubauen (Jeder kennt das vom Surfen ein Bild läd halb dann stokt es, um dann einige Sekunden später weiterzuladen) für jedes Spiel bei dem es auf die Reaktionszeit ankommt die logik jedoch Serverseitig läuft (Source games, Ut engine, nicht jedoch MMORPGS im allgemeinen) ist es daher wichtig UDP zu nehmen, was interessiert es schließlich nach Sekunden  noch mitgeteilt zu bekommen wo der Gegner war, es ist nur wichtig wo er ist.


----------



## tuxedo (9. Nov 2009)

Mit TcpNoDelay/Abgeschalteten Nagle-Algo ist das Delay bein senden so gering, dass sogar eine Audioübertragung möglich ist. 

Des weiteren ist es auch bei Ego-Shootern "problematisch" wenn einfach mal so ein Paket ankommt. Oder wird bei einem Schuss das ganze "nur Sicherheit" in 5 Paketen gesendet? Kann ich mir nicht vorstellen. Oder darf es vorkommen dass ich in CS auf nen Gegner ziele, abdrücke und, och schade, das Paket nicht abkommt und der Gegner doch noch mit dem Leben davonkommt?

Letzten endes müsste man also klassifizieren welche Pakete verloren gehen dürfen und welche nicht. 

Und wenn man rein auf UDP setzt, und dann wieder anfangen muss sicherzustellen dass (manche) Pakete auch tatsächlich ankommen: Tja, dann ist TCP wohl schneller als wenn man auf UDP selbst ein "Ich stelle sicher dass ein bestimmtes Paket auch tatsächlich ankommt"-Protokoll aufsetzt.

- Alex


----------



## Empire Phoenix (9. Nov 2009)

Wenn man kein Sortierung braucht, und nur selten zuverlässige Pakete sieht das ganze anders aus.


----------



## Gast2 (9. Nov 2009)

tuxedo hat gesagt.:


> Oder darf es vorkommen dass ich in CS auf nen Gegner ziele, abdrücke und, och schade, das Paket nicht abkommt und der Gegner doch noch mit dem Leben davonkommt?


ja - das passiert leider recht häufig



> Und wenn man rein auf UDP setzt, und dann wieder anfangen muss sicherzustellen dass (manche) Pakete auch tatsächlich ankommen:


nein ... wenn Du ein Lebensbitt für alle Spieler mit lieferst - bei jedem Paket - dann weis jeder Client immer wer tot ist

was meinst Du wieso manche Spieler immer stur geradeaus "surfen" ... weil kein Update beim Server ankam und der Server erstmal annimmt das der Spieler nichts geändert hat ... dabei wird intern eine "Kalkulation" vorgenommen was mit dem Spieler - auf Grund der letzten Eingaben - passieren würde ... Autorennen kannst Du mit der Halflife-Engine nicht spielen - weil der Algo für die Kalkulation bei Autos anders ist

wenn bei TCP ein Paket verloren geht, dann wird das Paket erneut angefordert ... und das kosten den Server Zeit die er nicht hat ... der Overhead für TCP ist wesentlich höher als bei UDP ... bei UDP benötige ich eine Socketverbindung ... bei TCP eine pro Spieler

hand, mogel


----------



## tuxedo (9. Nov 2009)

Definiere "selten"?!

Aber nichts desto trotz: Non-Blocking-Datagram gibts in Java nicht. Nur Non-Blocking-Sockets wenn man sich an JavaNIO wagt (oder eben xSocket, Mina, Netty, ... benutzt).

Dass es das nur blockierend gibt: Find ich jetzt auch nciht so schlimm wie bei TCP. 
Du spendierst dann halt einen Thread der in einer Endlosschleife die Daten liest. Ist nicht wirklich ein Problem.

Würde es Non-Blocking geben würdest du wohl auch einen Thread benutzen da du ja nicht deine GUI oder sonstwas mit dem Lesen der Daten wenn denn gerade welche ankommen belästigen willst. 
Threadsafe? Wo ist das Problem? Du hast doch nur einen Thread der liest.. Ob das jetzt der Main oder sonst einer ist, ist doch wurscht ...

- Alex


----------



## Empire Phoenix (9. Nov 2009)

Der Netzwerkcode is threadsafe, ja , aber je nach engine, darf man Objecte nur in der Update funktion innen RenderThread verändern, und da ist es ein echts Problem wenn der Thread die Daten auch verarbeitet, statt nur empfängt.


----------



## Empire Phoenix (9. Nov 2009)

Naja also eingentlich geht es schon:
YouTube - Garry's Mod Racer
YouTube - The Great Garry's Mod Race


----------

