DatagramSocket rausfinden ob recive möglich ohne zu blocken

Status
Nicht offen für weitere Antworten.

Empire Phoenix

Top Contributor
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)
 
T

tuxedo

Gast
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

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

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?
 
T

tuxedo

Gast
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

Top Contributor
Ä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.
 
T

tuxedo

Gast
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
 
G

Gast2

Gast
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
 
T

tuxedo

Gast
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

Top Contributor
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.
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen


Oben