Socket Verständinsfrage - Spieleprogrammierung DatagrammSocket

Raziell

Bekanntes Mitglied
Hallo zusammen,

habe da mal eine paar kleine Verständnisfragen für Client/Server Spieleprogrammierung.
Habe bis jetzt immer nur mit verbindungsorientierten Protokollen (Sockets) gearbeitet.
Dabei sind dann kleine Spielchen wie das Kartenspiel Schwimmen oder auch ein Chat a la ICQ
entstanden.

Da mir eine Socket-Verbindung zu langsam für z.B. die ständige Übertragung von x und y Koordinaten
(Broadcast) in einem Spiel sind, möchte ich eine DatagrammSocket-Verbindung nutzen.

Habe dazu schon 2 Beispiele gefunden:
1. Writing a Datagram Client and Server (The Java™ Tutorials > Custom Networking > All About Datagrams)
2. Broadcasting to Multiple Recipients (The Java™ Tutorials > Custom Networking > All About Datagrams)

Welches der beiden Beispiele ist denn relevant für mein Vorhaben?

Grüße
 
T

tuxedo

Gast
Nur so nebenbei:

Wenn du mit TCP sowas wie X/Y Koordinaten nicht schnell genug übertragen kannst dann machst du was falsch ..

RMI schafft Methodenaufrufe via TCP in gut 2,5 Millisekunden. Man kann damit auch prima eine Audioübertragung machen (und da hört man alles >50ms locker ..).

Der Trick dabei ist:

setTcpNoDelay aka. Nagle Algo abschalten.

- Alex
 

Empire Phoenix

Top Contributor
Der hauptvorteil von Udp sit eher der ping, mit meiner eigenen netzwerkimplementation kann cih pings von 1 ms schaffen (ist aber eh ehere netzwerkabhängig) zum boardcast, da müsste es reichen an die boardcastadresse des netztes zu schicken oder sehe ichdas falsch? (ist dann allerdings nicht mehr i net fähig, also lieber point to point nehmen)Generell wenn du cniht weißt welches, beide dann selber Gedanken machen, und bewerten welches eher deinen ansrpüchen genügt. Am rande sei noch JGN erwähnt, auch wenn ich das persöhnlich zu komplex aufgebaut finde.
 

Raziell

Bekanntes Mitglied
Hm ich glaube ich hab mich falsch ausgedrückt also ich habe vorher immer
mit Socket -> ServerSocket Verbindungen gearbeitet. RMI sagt mir jetzt garnichts.
´
Kurzes Beispiel wie ich das gemacht habe:

Client:

Java:
public class Client {

	private Client_GUI_Main client_GUI;
	private Socket sock = null;
	private OutputStream outstream = null;
	private String username = "";
	private String host = "";
	private int port = 6000;


	public Client(Client_GUI_Main client_GUI, String username, String host, int port) throws UnknownHostException, IOException {
		this.client_GUI = client_GUI;
		this.username = username;
		this.host = host;
		this.port = port;
		connect();
	}


	public void connect() throws UnknownHostException, IOException {
		sock = new Socket(host, port);
		outstream = sock.getOutputStream();
		new Client_Thread(sock, client_GUI, username);
	}


	public void sendDates(String daten) {
		try {
			outstream.write((daten).getBytes());
			outstream.write('\n');
		} catch (IOException e) {
			
		}
	}


}

Server:

Java:
public class Server extends Thread {

	private static final long serialVersionUID = 6086853045362042336L;
	private Server_GUI server_GUI = null;
	private Vector<GSocket> sockets = new Vector<GSocket>();
	private int port = 6000;
	private GSocket gsocket = null;

	
	public Server(Server_GUI server_GUI, int port) {
		this.server_GUI = server_GUI;
		this.port = port;
		start();
	}


	@Override
	public void run() {
		try {
			ServerSocket serverSocket = new ServerSocket(port);
			server_GUI.setInOutput("Server: Warte auf Verbindungen auf Port " + port + "...");
			while (true) {
				gsocket = new GSocket(serverSocket.accept());
				sockets.add(gsocket);
				new Server_Thread(gsocket, this, server_GUI);
				
			}
		} catch (IOException e) {
			
		}
	}


	}
	}


	public void broadcast(String content) {
		for (int i = 0; i < sockets.size(); i++) {
			OutputStream outstream = null;
			try {
				outstream = sockets.elementAt(i).getOutputStream();
				sendDates(outstream, content);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}


	private void sendDates(OutputStream outstream, String daten) {
		try {
			outstream.write((daten).getBytes());
			outstream.write('\n');
			server_GUI.setInOutput(daten);
		} catch (IOException e) {
			System.err.println("Fehler: sendDates()");
		}
	}

	public void addSocket(GSocket socket) {
		sockets.add(socket);
	}


	public Vector<GSocket> getSockets() {
		return sockets;
	}


}

Server Thread:

Java:
class Server_Thread extends Thread {
	private GSocket socket = null;
	private Server_GUI server_GUI = null;
	private Server server = null;
	private String inputString = null;
	private BufferedReader br = null;

	
	public Server_Thread(GSocket socket, Server server, Server_GUI server_GUI) {
		this.socket = socket;
		this.server = server;
		this.server_GUI = server_GUI;
		start();
	}

	@Override
	public void run() {
		try {
			br = socket.getBufferedReader();
			while (true) {
				inputString = br.readLine();
				if (inputString != null) {
					// Mach was
					
			}
		} catch (IOException e) {
			
		}
	}

}

Hoffe es hilft eucht weiter...

Danke im Voraus

Grüße
 
T

tuxedo

Gast
Der Code ist erstmal uninteressant.

Deine Aussage war dass TCP für das ständige übermitteln von X/Y Koordinaten zu langsam ist. Und eben das lässt sich nicht nachvollziehen wenn man weiß was der Nagle Algorithmus (Nagle-Algorithmus ? Wikipedia) ist, und wie man ihn abschaltet (Use Socket's setTcpNoDelay() - Real's Java How-to).

Wenn man dann noch an der richtigen Stelle ein
Code:
flush()
auf den Stream macht, dann ist man extrem nah an dem dran was UDP an Geschwindigkeit bringt. NUr eben mit all den TCP Vorteilen ...

- Alex
 

Raziell

Bekanntes Mitglied
Hi,

erstmal Danke für die Antwort, also ich habe jetzt
Java:
socket.setTcpNoDelay(true);
eingebaut.

An welcher Stelle wäre es in meinem Fall sinnvoll
Java:
flush();
einzuabuen?

Macht es nach dem
Java:
write('\n')
Sinn?

So sieht meine Methode zum Senden von Daten aus:

Java:
	public void sendDates(String daten) {
		try {
			outstream.write((daten).getBytes());
			outstream.write('\n');
		} catch (IOException e) {
			
		}
	}

Ich speichere jetzt mit Hilfe von System.currentTimeMillis, wann welcher Vorgang stattfindet.
Also OUT steht für rausschicken und IN für empfangen. Beim Server findet noch eine kleine
Verarbeitung statt, bevor er die Empfangenen Daten wieder an alle Clients rausschickt.

Hier meine Ergebnisse zur Messung:

  1. Client OUT: 1270723669581 Server IN: 1270723669589 Client IN: 1270723669589
  2. Client OUT: 1270723669681 Server IN: 1270723669686 Client IN: 1270723669687
  3. Client OUT: 1270723669781 Server IN: 1270723669790 Client IN: 1270723669790

Kann man pauschal sagen, dass die Verzögerungen so akzeptabel sind?

Danke im Voraus

Grüße
 
T

tuxedo

Gast
flush() bewirkt dass der Sendepuffer "geleert" wird, also "gesendet" wird.

Also macht es u.U. überall da Sinn, wo du eine Message abgeschlossen hast. Also am Ende deiner sendMessage Methode ...

Ohne das flush() sind 8ms schon recht gut. Mit flush() wirst du sicher in Richtung 1ms für eine Übertragung von A nach B in einem lokalen Netzwerk hingekommen. Die Rückantwort... Naja. Da kommts drauf an was dein Server in der zwischenzeit mit der Nachricht anstellt bis er die Antwort zurück gibt.

- Alex
 

Raziell

Bekanntes Mitglied
Hi,

habe es jetzt so realisiert:

Java:
	private void sendDates(OutputStream outstream, String daten) {
		try {
			outstream.write((daten).getBytes());
			outstream.write('\n');
			outstream.flush();
		} catch (IOException e) {
			
		}
	}

Dann lasse ich in einer Schleife einen String mit currentTimeMillis an den Server schicken,
dieser macht ebenfalss ein currentTimeMillis und berechnet die Differenz.

Das Problem ist, dass die Differenzen iwie. immer größer werden,
also Anfangs sind es mal so 5-10ms und nachher sind es fast nurnoch 40-60ms.


Woran kann das liegen?

Grüße
 

Raziell

Bekanntes Mitglied
Ok war ein kleiner Fehler von mir :)
Der Delay liegt jetzt zwischen 0 und 1 ms :toll:

Danke für die Hilfe :)

Aber keine Angst es kommen bestimmt noch mehr Fragen :D


Grüße
 

Kr0e

Gesperrter Benutzer
TCP ist aber für Spiele im LAN sowieso nicht das Allerbeste...
Versuch doch mal MulticastSocket.

Damit kann man ähnlich einem Broadcast aber genau definiert an eine ganze Reihe von
Mitspielern synchron senden!

Wenn du nämlich sehr viele Spieler hast... > 100 ... (Was im Lan allerdings schon selten ist... ;)) macht Multicast Sinn und TCP wäre dann einfach nur fehl am Platz. Wäre TCP für alles geeignet gäbe es kein UDP oder Multicast ;)

Allerdings hängt die Bandbreite natürlich stark von deiner Programmierung ab! Wenn du alle 30 ms Koordinaten an alle Spieler sendest, dann werden die Figuren "laggen". Wenn du zuviele Daten sendest, ist das Netz vollkommen überlastet! Und was ist wenn mal ne Verbindung langsam ist ? Dann hängen alle! Um ruckelfrei Spieler zu aktualisieren gibt es einige Tricks... Z.b. "Interpolation" Dabei wird erst auf ein update gewartet und dann auf das nächste... Wenn öfter als 30mal pro Sekunde gezeicchnet wird, kannst du interpolieren.. weil du weißt, wo das Objekt in z.b 10 ms sein wird... Alles in allem ist UDP/Multicast das gängige Protokoll für Spiele...(BF2, CSS, CS glaub ich auch...) Aber klar, TCP bekommt ähnlich niedriege Pings zustande. Aber bei TCP wird eben gewartet, wenn z.b. das TCP Window beim Empfänger voll ist... Bei hohen Latenzwerten sehr ungünstig für ein Spiel.

RMI macht natürlich vieles einfacher, aber grad bei einem Spiel mit vielen Usern sollte man davon die Finger lassen und sich schnell was eigenes impl. Ist ja nicht die Welt.... Liegt jetzt nicht wirklich an RMI sondern an TCP wie schon gesagt.... (Bei vielen Spielern!)

Gruß,
Chris
 
T

tuxedo

Gast
Kann ich so nicht ganz unterschreiben (nicht zu 100%, vllt. zu 50%)...

Mein Lieblingsbeispiel: World of Warcraft....

An so einem Server hängen seeehr viele (100 ist da keine Nennenswerte Zahl) Spieler. Und da wird mit TCP gearbeitet. Klappt bestens.

Klar, da wird auch nicht im 30ms Takt eine Spielerposition aktualisiert. Aber gehen tut das ohne Probleme.

Der vermeintliche Vorteil mit UDP "alle Clients gleichzeitig synchron zu erreichen" gilt nicht wirklich:

Man kann zwar mit einem einzigen Call eine Message absetzen die für alle gilt. Aber 1) ist es nicht zugesichert dass a) alle die Nachricht gleichzeitig erhalten b) die Nachricht überhaupt erhalten und 2) funktioniert das wenn, dann nur im lokalen Netz. Über's Internet kriegst du keinen Multicast/Boradcast zusammen. Also kann man Multicast/Boradcast wohl wieder aus deer Liste mit Vorteilen komplett streichen.

Wenn man nen 3D Shooter bastelt sollte man vllt. auch UDP umsteigen. Aber alles was nicht schneller als eine Audioverbindung sein muss macht mit TCP und einem anständigen Protokollansatz keinerlei Probleme.

RMI für Spiele: Nun. Hier gilt das gleiche. Mit RMI kann man natürlich ein Spiel umsetzen. Problemlos. Auch mit >100 Spielern. Aber im 30ms Takt eine Spielerposition zu aktiualisieren: Da muss man erstmal hinterfragen: Muss das sein? Geht's nicht auch anders? Und im worst-case nimmt man dann halt doch UDP.

Ich sag's mal so: In >90% der Fälle der hier über's Forum gebastelten Anwendungen/Spiele ist TCP (und von mir aus auch RMI) absolut und total ausreichend.
 

Kr0e

Gesperrter Benutzer
Ja das stimmt, wie gesagt... Im Lan Multicast... Du sprichst die Sache mit der Garantie an, dass die Daten auch ankommen...
Updates können durchaus mal vernachlässigt werden... Wird ja eh alle 30 ms geupdated.. iwas wird oft genug durchkommen.
TCP ist da nicht besser... Auch TCP ist ähnlich unsicher wie UDP bei der Übertragung ansich oder nicht ? Klar, es kommt an.. aber teilweise muss auch schonmal nachgeschickt werden (Natürlich vom Protokoll ansich).. Und das bringt Overhead mit sich...
Unnötigen Overhead...

Kenn ich zum Beispiel vom Dateikopieren im Netzwerk... Die ganze Zeit 80-90 % .. Dann gibet aber auch mal ganz kurze Einbußen von 4 - 10 %... Ich denke da gehen Pakete verloren , die über TCP neu angefordert werden. Ich meine TCP ansich sendet doch nicht besser als UDP. Liegen ja beide gleichhoch in der Netzwerkebene...

Bei jedem Online Spiel kennt man das doch auch... Ein kurzer "Lag" die Figueren rennen in eine komische Richtung und dann gehts direkt wieder... Das ist UDP wo mal ein Paket nicht durch kam... Aber was solls.. bei TCP wären davon dann ALLE Spieler betroffen und nicht nur der bei dem das Paket verloren gegangen ist. Außerdem hat UDP ne ziemlich hohe "Trefferrate"... Wirklich viel geht nicht verloren. Ob UDP gut läuft oder nicht hängt auch von der Programmierung ab.. Wenn man einen Socket mit UDP PAcketen bombadiert und der Socketpuffer zu kleine ist, dann gehen die Pakete beim Socket verloren und nicht im Netz... Wenn man mit UDP geschickt programmiert, kann man schon mit ziemlicher Sicherheit davon ausgehen, dass es durchkommt.. und wenn nicht ? tja, dann wartet das spiel eben mal 30ms auf das nächste Update.. ist ja auch kein Beinbruch...

Und dass bei Spielen wie WOW TCP ausreicht ist klar... Es kommt nicht auf 30 oder 60 ms an... Wenn man bei einem Egoshooter aimed oder nach vorne geht, dann muss das "instant" sein für das richtige Gefühl, ansonsten wird das Spiel wenige Fans haben...
Auch bei Strategiespielen reicht TCP aus... Aber alles andere wo schnell Daten übertragen werden müssen und durchaus mal ein Paket verloren werden kann... UDP!!!

Gruß,
Chris

PS: Um nochmal auf dein WOW Beispiel einzugehen... Du bekommst als Spieler bestimmt nicht die Daten ALLER Mitspieler sondern nur die von denen, die sich in deiner näheren Umgebung befinden... Kein normaler Gameserver würde sonst diese Menge an Daten handeln können. Bei MMORPG's spielen ja oft weit über 1000 Spieler... Was man auch merkt, wenn man in einem Bereich ist, wo sehr viele Spieler sind... Z.b. in Städten... Da versagt das Netzwerk schon etwas... Wären dann theoretisch 1000 Leute im Lan mit Multicast, wären 1000 Leute an einer Stelle überhaupt kein Problem... Und ich meine Multicast geht schon über Internet, sofern man glaub ich Software wie Hamachi einsetzt, die ein Lan simuliert... Bin ich mir aber auch nicht sicher, hab ich nur schonmal iwo gehört....
 
Zuletzt bearbeitet:
T

tuxedo

Gast
Ja das stimmt, wie gesagt... Im Lan Multicast... Du sprichst die Sache mit der Garantie an, dass die Daten auch ankommen...
Updates können durchaus mal vernachlässigt werden... Wird ja eh alle 30 ms geupdated.. iwas wird oft genug durchkommen.

Da hast du recht. Bei 30ms Updates ist es in der Regel vernachlässigbar wenn ein Paket mal nicht ankommt.

TCP ist da nicht besser... Auch TCP ist ähnlich unsicher wie UDP bei der Übertragung ansich oder nicht ? Klar, es kommt an.. aber teilweise muss auch schonmal nachgeschickt werden (Natürlich vom Protokoll ansich).. Und das bringt Overhead mit sich...
Unnötigen Overhead...

Womit wir bei der Aussage wäre:

UDP nimmt man da wo es wurscht ist wenn ein Paket mal nicht ankommt.
TCP nimmt man da wo man 100%ig sicher gehen will DASS ein Paket vollständig ankommt.

Kenn ich zum Beispiel vom Dateikopieren im Netzwerk... Die ganze Zeit 80-90 % .. Dann gibet aber auch mal ganz kurze Einbußen von 4 - 10 %... Ich denke da gehen Pakete verloren , die über TCP neu angefordert werden. Ich meine TCP ansich sendet doch nicht besser als UDP. Liegen ja beide gleichhoch in der Netzwerkebene...

"Dateikopieren im Netzwerk" ... Das ist eine seeehr ungenaue aussage. Wenn du damit den Dateitransfer über die "Windows Dateifeigabe" meinst: Da ist auch einiges an UDP mit dabei. Hatte noch nicht die Zeit da mal genauer rein zu schauen. Ich weiß nur dass es nicht 100% TCP ist.

Bei Dateitransfers wäre es quatsch UDP zu nehmen. Grund: Wenn ein Paketz mit UDP verloren geht muss ich das auf Anwendungsprotokollebene behandeln. Das kostet mehr, als wenn das direkt im TCP Layer passiert.

Mit der gleichen Netzwerkebene: Da hast du nicht ganz recht. Prinzipiell sind UDP und TCP schon gleich was due zuverlässigkeit angeht. Doch werden TCP Pakete von den vielen Routern/Gateways im Inet "vorsichtiger" behandelt als UDp Pakete. Denn die Router wissen ja auch: Ein TCP Paket unter den Tisch fallen lassen ist nicht im Sinne des Erfinders. Bei UDP ist das "per definition" nicht so schlimm. Ergo könnte man hier schon sagen dass TCP im Internet bevorzugt behandelt wird was das vehindern eines Paketverlusts anbelangt (Stichwort QOS).

Bei jedem Online Spiel kennt man das doch auch... Ein kurzer "Lag" die Figueren rennen in eine komische Richtung und dann gehts direkt wieder... Das ist UDP wo mal ein Paket nicht durch kam... Aber was solls.. bei TCP wären davon dann ALLE Spieler betroffen und nicht nur der bei dem das Paket verloren gegangen ist.

Das mit "in eine komisch Richtung rennen" kommt daher, dass bei vielen Spielen nicht (nur) die aktuelle Position übermittelt wird, sondern (hauptsächlich) die aktuelle Bewegungsrichtung und Geschwindigkeit. Der Client weiß dann also in welche Richtung er eine Figur rennen lassen muss. Und das tut er solange bis er einen Richtungswechsel bekommt, oder die Message ankommt dass der Spieler jetzt stehen geblieben ist. Das ist beim TCP basierten World of Warcraft so und auch bei vielen UDP basierten Shootern.
Nebenbei: Bei TCP wäre eben nicht alle Spieler betroffen. Denn jeder Spieler bekommt, wie bei UDP (nicht Multicast) ein eigenes Datenpaket. Nur bei TCP eben "sicher" und bei UDP "unsicher". Bei TCP kann es unter umständen einfach dauern bis die Figur wieder stehen bleibt. Bei UDP muss man im worst-case auf Anwendungsebene eine Fehlerbehandlung fahren. Stell dir vor die Figur soll rennen und dann auf einmal stehen bleiben. Wenn jetzt genau das Stehenbleiben Paket ausfällt, dann rennt die immer weiter, obwohl die Figur gerade stehen soll und in ihrem Inventar wühlt .. Das ist eben anders als wenn während dem rennen ein Positionsupdate verloren geht. Das ist nicht weiter schlimm. Du siehst: UDP ist nicht sooo einfach. Es hat seine Vorteile, aber auch seine Nachteile die man entsprechend behandeln muss.

Bei TCP dauert's im worst-case einfach länger. Aber man muss nix extra dafür tun.

Außerdem hat UDP ne ziemlich hohe "Trefferrate"... Wirklich viel geht nicht verloren.

Quelle?

Ob UDP gut läuft oder nicht hängt auch von der Programmierung ab.. Wenn man einen Socket mit UDP PAcketen bombadiert und der Socketpuffer zu kleine ist, dann gehen die Pakete beim Socket verloren und nicht im Netz...

Oha. Das ist ja mal eine Aussage. Kannst du das belegen? Würd' mich interessieren.

Wenn man mit UDP geschickt programmiert, kann man schon mit ziemlicher Sicherheit davon ausgehen, dass es durchkommt..

Das halte ich für ein Gerücht. Du hast absolut keinen Einfluss auf die UDP Pakete die durch beliebige Router im Netz schwirren. Erschwerend kommt hinzu dass nichtmal die Reihenfolge der Pakete zugesichert ist. Das sollte man nicht unbedingt komplett ignorieren. Nichtmal bei irgendwelchen Shootern. Weil erst sollte die Waffe geladen sein bevor man sie abfeuert.. Umgekehrt wäre nicht so gut.

und wenn nicht ? tja, dann wartet das spiel eben mal 30ms auf das nächste Update.. ist ja auch kein Beinbruch...

Habe ja schon aufgeführt warum man das so allgemein nicht stehen lassen kann. Ausnahmen bestätigen die Regel ...

Und dass bei Spielen wie WOW TCP ausreicht ist klar... Es kommt nicht auf 30 oder 60 ms an... Wenn man bei einem Egoshooter aimed oder nach vorne geht, dann muss das "instant" sein für das richtige Gefühl, ansonsten wird das Spiel wenige Fans haben...

Hab ich je was anderes behauptet? Meine Aussage war:
In >90% der Fälle der hier über's Forum gebastelten Anwendungen/Spiele ist TCP (und von mir aus auch RMI) absolut und total ausreichend.



Auch bei Strategiespielen reicht TCP aus... Aber alles andere wo schnell Daten übertragen werden müssen und durchaus mal ein Paket verloren werden kann... UDP!!!

Verwechsle "schnell Daten übertragen" nicht mit "geringe Latenz" ...
Kurz um:

UDP = möglichst geringe Latenz, 0% Sicherheit und 0% Ordnung
TCP = weitgehend geringe Latenz, 100% sichere und geordnete Übertragung

PS: Um nochmal auf dein WOW Beispiel einzugehen... Du bekommst als Spieler bestimmt nicht die Daten ALLER Mitspieler sondern nur die von denen, die sich in deiner näheren Umgebung befinden... Kein normaler Gameserver würde sonst diese Menge an Daten handeln können. Bei MMORPG's spielen ja oft weit über 1000 Spieler... Was man auch merkt, wenn man in einem Bereich ist, wo sehr viele Spieler sind... Z.b. in Städten... Da versagt das Netzwerk schon etwas...

Ist das bei UDP anders? Wenn man WoW auf UDP umstellen würde.. Was würde sich ändern? Maximal wäre in dünn besiedelten Regionen die Latenz besser. Aber dass es in Großstädten mit vielen >100) Spielern anfängt zu laggen liegt nicht an der zur Verfügung stehenden Bandbreite der Netzwerkleitung oder des UDP/TCP Kommunikationskanals. Das liegt vielmehr daran dass die Clients zu viel anzeigen müssen (Stichwort Polygone) und der Server in dieser Region der Karte zu viel Interaktion hat die er nicht mehr adäquat bewältigen kann.

Wenn du mal selbst nen MMORPG Gameserver mit >200 Spielern hattest merkst du das ganz schnell ;-)

Ich will TCP nicht als allheilmittel hinstellen, aber in extram vielen Fällen ist TCP super ausreichend und dazu noch einfach. Man sollte ben gut abwägen ob man sich den UDP Stress gibt und wieviel Nutzen man daraus zieht, bevor man TCP den Rücken kehrt.

- Alex
 
Zuletzt bearbeitet von einem Moderator:

Empire Phoenix

Top Contributor
Naja mit udp nen zuverlässige ebene zu bauen ist nciht schwer, und wenn man udp nimmt, kann man auch entscheiden was mus zuverläassig sein, was nicht, (bei den meisten games hat man wenige zuverlässige und sehr viele unzuverlässige sachen)

Bei tcp wird man halt bei jeder übertragen zu dem overhead gezwungen.
 

Kr0e

Gesperrter Benutzer
Versteh mich nicht falsch Tuxedo, ich find auch TCP besser, dennoch sollte man UDP nicht außer Acht lassen, denn das passiert wenn man nur von negativen Seiten erfährt. DA wollte ich halt noch die guten seiten von UDP auflisten und vorallem Multicast...

Ich halte wiederum was anderes für ein Gerücht:

"Das liegt vielmehr daran dass die Clients zu viel anzeigen müssen"

Es gibt weitaus grafikintensivere Spiele als Warcraft... Die Polygone sind sowieso nur Models die sich bereits als Displayliste auf der Grafikkarte befinden. ICh glaube schon, dass es da am Netzwerk liegt, dass alles rum "laggt".

Und nochmal zurück zum Thema, was UDP da verbesseren könnte... Ich habe da von Multicast gesprochen, nicht von UDP...
UDP verbessert daran natürlich nichts, da geb ich dir Recht!


" Ob UDP gut läuft oder nicht hängt auch von der Programmierung ab.. Wenn man einen Socket mit UDP PAcketen bombadiert und der Socketpuffer zu kleine ist, dann gehen die Pakete beim Socket verloren und nicht im Netz... "

" Oha. Das ist ja mal eine Aussage. Kannst du das belegen? Würd' mich interessieren. "

Jain, ich kenne das halt einfach aus Erfahrung. Du kannst das ja ganz leicht selbst mal testen... Schreib nen DatagramSocket der auf Daten wartet. (Z.B. mit einem Socket Puffer von sagen wir .. 1024 kb)

Nun sende ein paar Pakete mit 1000 KB Daten. Meines Wissens kommt das erste an, und der Rest geht verloren. (Wenn man das 1. nicht mit socket.receive() ausliest natürlich...) Selbstverständlich gehen auch Pakete im Netz verloren.


"
Außerdem hat UDP ne ziemlich hohe "Trefferrate"... Wirklich viel geht nicht verloren.

Quelle?
"

Kann ich dir leider nicht direkt nennen, ich ziehe meine Tests heran, die ich damit mal gemacht habe, bei denen UDP im Lan und auch im Internet recht zuverlässig war... (Wollte vor einiger Zeit genau das mal testen...) Vlt. gibts dazu ja Berichte, ich werde mal suchen! Um das mal in Zahlen auszudrücken... Ich hab ne Datei von knapp 2GB über UDP in 2048 KB Paketen geschickt. Von ungefähr 1000 Paketen kamen teilweise weniger als 20 nicht an... Das würde ich als recht gut bezeichnen ... 2 % Fehlerquote bei meinen (Zugegeben nicht ausgereiften) Tests...

Und das meinte ich jetzt mit der Programmierung... Die Tests waren z.b. ziemlich mies, als ich nur jede Millisekunde gelesen hab, da ging ne ganze Menge verloren.

Also, tut mir Leid. Eine direkte Quelle kann ich dir nicht nennen.

Gruß,
Chris
 
W

whatever

Gast
Aber dass es in Großstädten mit vielen >100) Spielern anfängt zu laggen liegt nicht an der zur Verfügung stehenden Bandbreite der Netzwerkleitung oder des UDP/TCP Kommunikationskanals. Das liegt vielmehr daran dass die Clients zu viel anzeigen müssen (Stichwort Polygone) und der Server in dieser Region der Karte zu viel Interaktion hat die er nicht mehr adäquat bewältigen kann.

Bei beispielsweise 500 Spielern auf einem Fleck müssen an jeden Spieler 499 Positionen gesendet werden, also überschlagen 250.000 ausgehende Updates. Ein Update alle 30ms würde bedeuten 33 Updates die Sekunde, also ~ 8.000.000 Positions-/Spieler-Updates die Sekunde.
Bandbreite kann definitiv eine Rolle spielen.

Clients würde ich heutzutage fast ignorieren, insbesondere bei älteren Games.
Viel wichtiger sind Serverressourcen und Netzwerk.
 

Raziell

Bekanntes Mitglied
Hi,
hätte nochmal eine kurze Verständnisfrage.
Also wenn Spieler A sich beispielsweise nach rechts bewegt, dann will ich es so realisieren,
dass er in diesem Moment praktisch nur den Tastendruck an den Server schickt.
Dieser kennt natürlich die Position des Spielers und kann diese Neu berechnen.
Der Client sendet somit nur 'Statusänderungen' an den Server.

a) Ist es jetzt sinnvoll es so zu realisieren, dass der Server die ständig Neu
berechnete(n) Position(en) an die Spieler sendet und diese dann daraufhin die anderen Spieler
neu zeichnen? oder...

b) Ist es sinnvoll, wenn der Server den Clients praktisch ebenfalls nur den Tastendruck sendet
und diese dann die neuen Positionen ermitteln und zeichnen?

Ich denke a) ist sinnvoller, da die Berechnungen ja hauptsächlich auf dem Server und nicht auf den Clients stattfinden sollten? Bei Fall a) würde man die Clients entlasten und bei Fall b) wiederrum würde man den Server entlasten (Was ja eigtl. nicht der Sinn der Sache ist oder?).


Grüße
 
Zuletzt bearbeitet:

Kr0e

Gesperrter Benutzer
Also, 1. wenn du nen Tastendruck an den Server sendest, dann sollte der damit deine neue position berechnen, aber noch nicht die anderen informieren! Dies geschieht dann in Folge der regelmäßigen Updates, alle 30 ms oder so... Die Clienten sollten nix an den Positionen drehen... damit könnten ja ganz leicht Hacks gemacht werden.... Ein Client z.b. kann dem server ständig was schicken bekomtm aber nur alle 30 ms ein Update. Hier musst du noch evt eine Taktik verfolgen, damit es besser spielbar ist:

Das nennt sich in der Netzwerktechnik "Movement prediction". Dein Client schickt den move-Befehl und aktualisiert sich dann shconmal selbst, damit die Bewegung sofort spürbar ist. Wenn nun das nächste Paket eine andere Position hat, ist da was schief gelaufen, dann muss deine Position angepasst werden. Wenns aber gut geht, (was es ansich immer tut) dann hast du keine Verzügerung beim Gehen... Sehr gut fürs Spielgfühl. So macht es auch die Source-Engine. Gab da mal ein Wiki-Bericht dazu..

Gruß,
Chris
 

Empire Phoenix

Top Contributor
Gut source engine, großes NAJA!!
Renn einfach in Css direkt einem andren spieler hinterher ->
Vor mir ist was, kann nciht gehen, schicke befehl trotzdem an Server, clientspiler bleibt stehen
-> Server sagt, wieso der ist da garnicht mehr geht -> vorwärtslag. Über sachen wie physic boote, oder phys maps wollen wir mal garnicht reden.

Source Multiplayer Networking - Valve Developer Community

Dann haben wir das Gegenteil, alte bf1942, oder Quake3, man rennt auf mauer zu drückt springen, springt mit lag verzögerung, schafft es nicht über die mauer, zudem hat man eine leicht spürbare verzögerung.

Methode drei: Der spiele bewegt sich Clientseitig, und sendet updates an den server von seiner Position, der sendet das an die anderen die dann alles dazwischen einfach simulieren, machen viele MMORPGS so, aber spätestens in egoshootern auch mist, weil: Du siehst Gegner, schisst auf den, obwohl er bei sich schon in deckung gerannt ist. Jetzt können 2 sachen passieren:
Er hat bereits sein update an den Server geschcikt und es wurde verarbeitet, aus Serverscht schisst du ins nirgetwo, obwohl bei dir evtl sogar Blut kommt (Passiert auch in der Source engine,btw spiel mal auf laggenden servern), oder er hat das update noch nciht geschickt, und wird aus seiner Sicht durch eine Mauer erschossen (Cod moderwarfare2 sag ich nur).

Egal was du machst, du hasst immer nachteile und vorteile, hängt nur von dem was du machen willst ab.
(zb bei einer Panzersimulation ist es nicht ganz so schlimm, wenn der minimal verzögert reagiert, das deckt sich sowieso mit dem normalen verhalten (Panzer kommen nicht durch den Tüv bremsentest, ect^^))
Bei einem Ut ähnlichen Shooter, kommt es eher darauf an, das du das Gefühl hast schnell reagieren zu können, minimale ungenauigkeiten fallen hierbei nicht ganz so stark auf.
 

Kr0e

Gesperrter Benutzer
Jop, genau den Artikel meinte ich! Danke fürs wiederfinden :p Tja, da geb ich dir Recht, gibt immer Probleme... Aber ohne Movement Prediction wirkt das Spiel halt ein wenig träge. Ein weiteres schlechtes Beispiel ist BF2... Das ist einfach nur grottig was Netzwerk angeht (Vermutlich weil es sehr informationsreich ist... Keine Ahnung) Online ruckelt eigentlich generel immer iwas und wer kennt das nicht.. man srpingt in Deckung und stirbt, obwohl man bereits in Dekcung ist. Schlusswort: Nur im Lan kann man es Annähernd perfekt machen... Sobald hohe Latenzen im Spiel sind, ist das doch alles ein einziges rumgeflicke. Die Technik, die bei vielen MMORPG's angewendet wird, ist in der Tat unbrauchbar für Egoshooter. Als ich finde, die Source Engine macht das schon ganz gut... Ich meine.. ist ja auch ein schweres Unterfangen... Und wie du schon sagst, wenn jetzt noch Physik dazu kommt... ojeoje...

Aber im Prinzip höre ich bei deiner Argumentation eher ein Pro Source Engine raus... Denn die Alternativen sind ja nicht besser.. Ich persönlich hab lieber mal nen vorwärtslag als ein durchgehend träges Movement... Ist meine Meinung.

Wie gesagt, im Lan kannst die gute alte Quake, bf1942 Strategie ohne Probleme anwenden. Bei flotten Rechnern und einem guten Switch ist die Latenz im Normalfall 1-2 ms. Was so ziemlich instant ist. Außerdem geht, wie schon erwähnt, Multicast im Lan. Wer mit sagen wir.. 60 Leuten (Ich weiß, unrealistische Zahl im Normalfall) im lokalen Netz über TCP zockt, muss Differenzen von
(in meinem Beispiel) 1-2 ms * 60 User in Kauf nehmen. Sprich im schlimmsten Fall erfährt der 60te User erst 120 ms später von einem Kill oder Treffer oder was acuh immer als User 1... Aber ist jetzt nur ein Gedankenmodell. Praktisch kann man das nie so genau berechnen...


Gruß,
Chris
 

Empire Phoenix

Top Contributor
Joa, wobei wie icha cuh sagte das no prediction model vorteile hat bei fahrzeugsimulationen, panzern und so.
Prediction ist halt bissle hakelig, ich benutze für meine sachen ne mischung, zb drehen und so local per updates, flugbewegungen serverseitig, ohne prediction aber halt mit interpolation.

Ps source ist nicht schlecht, aber wenn du die mal zb. Garrysmod angeguckt hast, wirste da mehr probleme haben als mit leichter trägheit. Anderes beispiel sind slide maps in Css, da denkste du bist schon geduckt und dann haut dein kopf gegens hinderniss^^(einfach mal nach slide_ suchen im map filter wird innerhalb von 2 mins spilen klar wie ich das meine)

Genrell für shooter stimme ich aber zu, bereit bei rennspielen sieht das aber komplett anders aus,bei panzern wie bf1942 ebenfalls, strategie spielen sowieso und MMORPGS je nach angestrebter interaction/Steuermethode, letzendlich gibt es dann noch cheatanfällige lösung treffer clientseitig zu berechnen, denke der Nachteil ist offensichtlich, und das deckungsproblem bleibt dennoch.
 
T

tuxedo

Gast
Egal was du machst, du hasst immer nachteile und vorteile, hängt nur von dem was du machen willst ab.

Danke. Wenigstens einer hat mich verstanden...



whatever hat gesagt.:
Bei beispielsweise 500 Spielern auf einem Fleck müssen an jeden Spieler 499 Positionen gesendet werden, also überschlagen 250.000 ausgehende Updates. Ein Update alle 30ms würde bedeuten 33 Updates die Sekunde, also ~ 8.000.000 Positions-/Spieler-Updates die Sekunde.
Bandbreite kann definitiv eine Rolle spielen.

Nenn mir ein 3D Shooter bei dem 500 Spieler gleichzeitig in Sichtweite stehen ...

"Das liegt vielmehr daran dass die Clients zu viel anzeigen müssen"

Es gibt weitaus grafikintensivere Spiele als Warcraft... Die Polygone sind sowieso nur Models die sich bereits als Displayliste auf der Grafikkarte befinden. ICh glaube schon, dass es da am Netzwerk liegt, dass alles rum "laggt".

Ja, es gibt Grafikintensivere Spiele. WoW ist ein Spiel mit recht wenigen Polygonen. Richtig. Aber das ist auch gut so. Aber man muss zwischen Netzwerk-Lagg und Grafik-Lagg unterscheiden...

Eine Figur in WoW hat, ohne großartig Ausrüstung, um 1000-1300 Polygone. Nehmen wir jetzt nur mal 300 Spieler mit uppiger Rüstung (was in WoW nichts seltenes ist). Also sagen wir mal 300 * 2000 Polygone = 600.000 Polygone. Dazu kommen noch die Polygone für die Stadt in der die Spieler rumstehen plus die Texturen.
Ich finde das für eine 3D GameEngine, die schon über 5 Jahre auf dem Buckel hat, doch schon ausreichend viel um in die Knie zu gehen. Aktuelle Grafikkarten sind zwar schnell. Aber da hat die Performance der Engine selbst nix davon.
Geh mal in WoW in eine Großstadt. Selbst mit aktueller Grafikkarte bricht da die FPS zusammen. Da kann das Netzwerk nix für.

Und um ganz sicher zu gehen hab ich nen Kollegen von mir, aktiver WoW Spieler auf den offiziellen Servern, gefragt wie das bei ihm in dern Städten ist. Ob die Latenz in den Keller geht oder die FPS ...
Ergebnis:
hm, ums genau zu nehmen, ich habe sogar massive einbrüche. von 60 FPS runter auf 18 FPS, und das bei ner ATI 4890 mit 1 Gig speicher
jetzt sagt bitte nochmal einer dass WoW da die Bandbreite ausgeht ...

whatever hat gesagt.:
Clients würde ich heutzutage fast ignorieren, insbesondere bei älteren Games.

Hab ich ja eben versucht zu widerlegen ...

Gehen wir mal anders an die Sache. Ein durchschnittliches Datenpaket in WoW hat um die 20-30byte (wenn ich mich recht erinnere).
Ein Server packt rund 10mbyte/sek ... Geht man nun von 25byte/Paket aus, packt der Server also rund 400.000 Pakete/Sek bevor seine Leitung den Geist aufgibt.
Und so ein MMORPG Server stellt nicht alleine die ganze Welt dar. Das ist ein kleiner aber feiner Cluster aus mehreren Servern die unterschiedliche Teile der virtuellen Welt managen. Ergo müsste es ein vielfaches von 400.000 Paketen pro Sekunde sein was das Spiel Serverseitig verschicken kann.

Sehe da also noch keine Performanceprobleme auf der Netzwerkleitung. Eher in der Verarbeitung der vielen Daten in der Serverlogik.

whatever hat gesagt.:
Viel wichtiger sind Serverressourcen und Netzwerk.

Ich denke eher Serverressouercen als Netzwerk. Und das kann ich aus eigener Erfahrung (betreibe seit 2005 nen MMORPG Server) berichten. RAM und CPU Power sind hier am wichtigsten. Wobei RAM fast noch wichtiger ist als CPU. Die Maps und VMaps brauchen einiges an Speicher. Wenn das stöndig von der Platte geladen werden muss entstehen unnötige Latenzen. Hat man sie im RAM geht's super fix.

Kr0e hat gesagt.:
Und nochmal zurück zum Thema, was UDP da verbesseren könnte... Ich habe da von Multicast gesprochen, nicht von UDP...

Mag sein. Aber Multicast übers Inet ... Das entspricht nur leider nicht der Realität. Und in der heutigen Zeit wird nunmal übers Inet gezockt.

Kr0e hat gesagt.:
Ob UDP gut läuft oder nicht hängt auch von der Programmierung ab.. Wenn man einen Socket mit UDP PAcketen bombadiert und der Socketpuffer zu kleine ist, dann gehen die Pakete beim Socket verloren und nicht im Netz... "

" Oha. Das ist ja mal eine Aussage. Kannst du das belegen? Würd' mich interessieren. "

Jain, ich kenne das halt einfach aus Erfahrung. Du kannst das ja ganz leicht selbst mal testen...

Danke. Das muss ich nicht erst testen. Wir haben hier im Büro ein recht großes Gigabit-Netzwerk in dem über ein Dutzend digitale multicast Videostreams verfügbar sind. Wenn man zu viel aus einer Ecke des Netzes an Videos anzapft, dann geht der Managed Switch in die Knie und fängt an "unwichtige" Pakete zu droppen. Und rate mal was "per default" vom Switch als unwichtig angesehen wird? Richtig. UDP. Da kannst du noch so gut programmieren: Wenn ein Router meint er müsse droppen, dann tut er das. Da hast du keinen Einfluss drauf. Und quer durch's Internet hast du unendlich viele solcher potentieller "UDP Paket dropper" stehen.

Kr0e hat gesagt.:
Kann ich dir leider nicht direkt nennen, ich ziehe meine Tests heran, die ich damit mal gemacht habe, bei denen UDP im Lan und auch im Internet recht zuverlässig war... (Wollte vor einiger Zeit genau das mal testen...) Vlt. gibts dazu ja Berichte, ich werde mal suchen! Um das mal in Zahlen auszudrücken... Ich hab ne Datei von knapp 2GB über UDP in 2048 KB Paketen geschickt. Von ungefähr 1000 Paketen kamen teilweise weniger als 20 nicht an... Das würde ich als recht gut bezeichnen ... 2 % Fehlerquote bei meinen (Zugegeben nicht ausgereiften) Tests...

20 von 1000 ist für mein empfinden viel wenns um Dateikopiren geht.

Solltest den Test mal mit TCP im gleichen Netz wiederholen und rausmessen wieviele TCP Pakete neu angefordert werden... DAS wäre interessant.

Empire Phoenix hat gesagt.:
Bei tcp wird man halt bei jeder übertragen zu dem overhead gezwungen.

Hat sich mal jemand mit dem Overhead beschäftigt oder geschaut wieviel das ist?
Ich schon:

http://de.wikipedia.org/wiki/User_Datagram_Protocol#Eigenschaften hat gesagt.:
... wovon der IP-Header und UDP-Header insgesamt mindestens 28 Bytes belegen.

http://de.wikipedia.org/wiki/Transmission_Control_Protocol#TCP-.2FIP-Paket-Gr.C3.B6.C3.9Fe hat gesagt.:
TCP- und IP-Protokoll definieren jeweils einen Header von 20 Bytes Größe.

Ergo:

UDP: mind. 28byte
TCP: 40 byte
Differenz: maximal 12 bytes

Bei heute verfügbaren Bandbreiten kann man IMHO ich in jedem Fall vernachlässigen.

So, genug kontra geboten... Wer mit mir weiter diskutieren will bitte mehr als subjektive einschätzungen liefern ;-)
 
Zuletzt bearbeitet von einem Moderator:

Kr0e

Gesperrter Benutzer
Wieso profitiert eine alte Engine nicht von der Geschwindigkeit neuer Grafikkarten ?
Ne Engine basiert auf OpenGL oder DirectX. Eine neue Grafikkarte unterstützt beides jeweils besser als eine alte.
Multicore ist sowieso egal beim Rendern, da nur in einem Thread gerendert wird. Eine alte Engine kann
vlt. nicht die neuen Techniken, aber natürlich bringt ne schnelle Grafikkarte was bei Wow oder bei jedem
anderen älteren Spiel. Es sei denn, es gab noch keine Displaylisten bei Wow, aber das wage ich zu beweifeln.

Und wie ich bereits sagte. Die Grafikkarte zeichnet nicht 600.000 Polygone neu.
Es gibt Displaylisten. Die erfordern null GPU Leistung. Können sogar bei zu kleinem VRAM auf
den RAM ausgelagert werden. Die Umgebung ist eine einzige statische Display liste. Dazu die paar models.
Ich würde wetten, Spiele wie Crysis haben sehr viel mehr Polygone...

Ist aber ansich auch alles egal. Das Hauptthema war ja was ganz anderes. Und selbst wenn UDP Packets
gedropped werden, ist das so schlimm ? UDP Dateitransfer ist sogar garnicht mal schlecht. Jedes Paket
bekommt ne nummer die die Position des Buffers in der DAtei beschreibt. Am ende forderste einfach die Pakete nochmal
an die flöten gegangen sind. Solange bis alles da ist. So muss man nicht (Wie TCP z.b.) warten bis jedes Paket der
Reihe nach eintrudelt. Wie gesagt UDP hat seine Daseinsberechtigung. Und mit Overhead meinte mein Vorredner bestimmt
nicht 12 Byte Headersize mehr. Der Overhead der allein durchs Protokoll hinzukommt und nicht IMMER gebracuht wird
ist hier das Problem.
 
T

tuxedo

Gast
Wieso profitiert eine alte Engine nicht von der Geschwindigkeit neuer Grafikkarten ? Ne Engine basiert auf OpenGL oder DirectX. Eine neue Grafikkarte unterstützt beides jeweils besser als eine alte.
Multicore ist sowieso egal beim Rendern, da nur in einem Thread gerendert wird. Eine alte Engine kann
vlt. nicht die neuen Techniken, aber natürlich bringt ne schnelle Grafikkarte was bei Wow oder bei jedem
anderen älteren Spiel. Es sei denn, es gab noch keine Displaylisten bei Wow, aber das wage ich zu beweifeln.

Du drehst einem das Wort im Mund rum :-(

Ich hab geschrieben dass die ENGINE nicht schneller wird. Und mit ENGINGE meine ich in dem Fall nicht allein OpenGL/DX, sondern die Logik die oben drauf sitzt. Szenengraph etc. blabla. Da hilft dir eine 5x schnellere Grafikkarte auch nicht. Weiter unten, da wo dann OpenGL greift. Ja, da wird's mit einer besseren Grafikkarte schneller. Aber wenn's oben schon bremst, hilft dir's nix wenn's unten super schnell geht.

Und wie ich bereits sagte. Die Grafikkarte zeichnet nicht 600.000 Polygone neu.
Es gibt Displaylisten. Die erfordern null GPU Leistung. Können sogar bei zu kleinem VRAM auf
den RAM ausgelagert werden. Die Umgebung ist eine einzige statische Display liste. Dazu die paar models.
Ich würde wetten, Spiele wie Crysis haben sehr viel mehr Polygone...
Crisis und Co. sind auch nen ticken neuer als WoW, oder etwa nicht.
Unumgänglicher Fakt ist: Die FPS Zahl geht in großen Städten wo sich seeehr viele Polygone tummeln extrem in den Keller. Wie soll das mit dem Netzwerk zusammenhängen? Wenn der Server im Stress ist und Pakete nicht schnell genugausliefern kann, wenn der Client gerade ne vollgestopfte DSL-Leitung hat, dann fängt es an zu "laggen". DAS sind dann Netzwerk-Laggs. Die angezeigte FPS ist aber nach wie davon unbeeindruckt. Fakt Ende.

Ist aber ansich auch alles egal. Das Hauptthema war ja was ganz anderes. Und selbst wenn UDP Packets gedropped werden, ist das so schlimm ?

Zum x-ten mal: Ja, aber nur da wo man mit verloren gegangenen Problemen per se ein Problem hat. Audiotransfer, Positionsupdates im 30ms Takt und Co. lässt das kalt.
bei Dateitransfers fängts mit zunehmender Drop-Rate an zu nerven.

UDP Dateitransfer ist sogar garnicht mal schlecht. Jedes Paket bekommt ne nummer die die Position des Buffers in der DAtei beschreibt. Am ende forderste einfach die Pakete nochmal an die flöten gegangen sind. Solange bis alles da ist. So muss man nicht (Wie TCP z.b.) warten bis jedes Paket der Reihe nach eintrudelt.

Relativ... Okay, bleiben wir mal beim Dateitransferbeispiel.

Fangen wir mit UDP an... Geht hier ein Paket verloren, muss ich auf Anwendungsprotokolllevel das Paket nochmal anfordern. Ich hab mit durch die Verwendung von UDP zwar Wahnsinnige max. 12 bytes pro Paket gespart, muss dann aber auf Protokollebene nochmal ein Paket anfordern.

TCP ... Geht hier ein Paket verloren oder kaputt, wird es vom TCP Stack umgehend neu angefordert. Das geschieht unterhalb des Anwendungsprotokolls direkt im TCP Stack. Der Overhead ist hier (ich habs noch nicht nachgerechnet) sicherlich geringer als wenn man das auf UDP Anwendungsprotokolleben macht. Denn das sind mind. 29 bytes... In einem "richtigen" Protokoll eher um die >=35 bytes allein für's erneute anfordern des Paketes

Wie gesagt UDP hat seine Daseinsberechtigung. Und mit Overhead meinte mein Vorredner bestimmt nicht 12 Byte Headersize mehr. Der Overhead der allein durchs Protokoll hinzukommt und nicht IMMER gebracuht wird ist hier das Problem.

Wenn es nicht der Overhead durch den größeren TCP Header ist, was für ein Overhead ist es dann?

Mit Streams arbeitet man doch einfacher als mit Datagrammen?

Nach wie vor gilt:

UDP da wo es Sinn macht auf einzelne Pakete verzichten zu können
TCP da wo man auf nix verzichten kann und will.

- Alex
 

Raziell

Bekanntes Mitglied
Hallo zusammen,
erstmal vielen Dank für eure Antworten.
Ich werde jetzt einen neuen Thread in Spieleprogrammierung eröffnen,
da meine Fragen dann schon speziell auf Spieleprogrammierung im Netzwerk eingehen werden (Oder kann das hier bleiben?).

Bis dahin

Vielen Dank

Grüße
 
T

tuxedo

Gast
Bitte bitte, keine Ursache.

Du kannst du den Thread mit dem "Thema als "erledigt" markieren" Button übrigens abhaken ...

- Alex
 

Empire Phoenix

Top Contributor
Overhead tcp mla simple, bleiben wir bei deinem beispiel, 500 spiler a x packete sekunde blabla, davon sind ca 90% posiitonsupdates und so, -> pro sekunde werden mehree tausend packte gar nicht erst vom tcpstack bearbeitet, der übrigens in software ist. (Der grund warum man mac adressen fälschen kann), das kann man sparen, auch wird bei mieser verbindung bei udp nicht alles zurückgehalten wenn ein apcket fehlt, bei tcp bracht das dann mindestens nochmal die latenz bis das da ist, und alle anderen packete weiterverarbeitet werden können, die dann evtl schon veraltetet sind und datenmüll(positionsupdates), dann jedoch zusätzlich die logic beanspruchen.

Zudem gibt es neben den droppern auch unendlich verzögerer, router die bei engpässen alle tcp verbindungen verlangsamen, wodurch die daten zwar zuverlässig ankommena ber die latenz extrem steigen kann -> ergebnis ist eine extreme trägheit,statt laggen dann, beides mist.
Am rande, das stream system in tcp hat das problem, das wenn durch einen bug/übertragungsfehler(crc32 ist nicht 100% eindeutig) ein bit falsch ist je anch verarbeitung danach nichts mehr sinnig gelesen werden kann.
 
T

tuxedo

Gast
Overhead tcp mla simple, bleiben wir bei deinem beispiel, 500 spiler a x packete sekunde blabla, davon sind ca 90% posiitonsupdates und so, -> pro sekunde werden mehree tausend packte gar nicht erst vom tcpstack bearbeitet, der übrigens in software ist. (Der grund warum man mac adressen fälschen kann),

Woher hast du das denn? Was ist mit großen Webservern? Was ist mit großen Mailservern?
Wieso kann ich mit meiner SIMON Implementierung >10.000 Nachrichten pro Sekunde am Server entgegen nehmen und auch beantworten?

das kann man sparen, auch wird bei mieser verbindung bei udp nicht alles zurückgehalten wenn ein apcket fehlt, bei tcp bracht das dann mindestens nochmal die latenz bis das da ist, und alle anderen packete weiterverarbeitet werden können, die dann evtl schon veraltetet sind und datenmüll(positionsupdates), dann jedoch zusätzlich die logic beanspruchen.

Gut. Da sprichst du gleich wieder einen Unterschied von TCP<->UDP an. Bei TCP ist halt die korrekte Reihenfolge der Pakete zugesichert. In vielen Fällen macht das Sinn. In vielen anderen Fällen nicht. Jedem das seine. Nichts andere versuche ich hier auf den Punkt zu bringen.

Zudem gibt es neben den droppern auch unendlich verzögerer, router die bei engpässen alle tcp verbindungen verlangsamen, wodurch die daten zwar zuverlässig ankommena ber die latenz extrem steigen kann -> ergebnis ist eine extreme trägheit,statt laggen dann, beides mist.
Das ist wohl war. Aber auch hier kann man Filetransfers und Spiele nicht über einen Kamm scheren. Wenn TCP einen Engpass hat, dann wohl auch UDP. Ergo: Wenn ein Filetransfer über TCP in so einen engpass läuft, wird's mit UDP kaum besser gehen.

Bei Spielen die auf Paketreihenfolge und zugesicherter Übertragung es nicht ganz so eng sehen und deshalb auf UDP bauen besteht die Chance dass andere Pakete evtl. schneller sind. Aber alles in allem: Engpässe bremsen UDP und TCP wohl gleichermaßen.

Am rande, das stream system in tcp hat das problem, das wenn durch einen bug/übertragungsfehler(crc32 ist nicht 100% eindeutig) ein bit falsch ist je anch verarbeitung danach nichts mehr sinnig gelesen werden kann.

Ich würd's nicht ganz auf den Stream schieben. Mehr oder weniger hast du bei UDP auch einen Stream. Nur eben ist die Reihenfolge der Daten u.U. nicht korrekt.
Spätestens mit NIO hat man keine Stream-Klassen mehr. Aber gut. Den gleichen Gedanken hab ich auch schon bei meiner SIMON implementierung verfolgt..."Soll ich eine Fehlerüberprüfung einbauen oder nicht?".
Ich kam zum Schluss es nicht zu tun. Warum? Ganz einfach: Bei TCP sorgt TCP dafür dass alles passt. Innerhalb von TCP mag es zu CRC Fehlern kommen. die Werden aber von TCP selbst schon behandelt und korrigiert (bzw. Daten neu angefordert).
Alles was auf TCP aufbaut ist die Anwendung selbst. Und da kann es nur Bitfehler oder sonstiges geben wenn ein Programmierfehler vorliegt. Und eine Fehlerkorrektur für Bugs? Nun. Lieber beheb ich den Bug als mit einer Fehlerkorrektur für einen von mir verursacnten Fehler zu leben.

Nebenbei kann das gleiche mit UDP auch passieren. Da hast du aber nicht allein das problem dass der Entwickler zu doof war keine Bugs einzubauen, nein. Da musst du dich in der Tat noch um CRC kümmern. Denn einfach so ungesehen jedes ankommende Paket so anzunehmen ist da u.U. gefährlich. Könnte ja ein Bitfehler drin sein der die ganze Programmlogik kippt....:shock:

Und um's nochmal zu erwähnen:

UDP da wo es Sinn macht auf einzelne Pakete verzichten zu können und wo einem die Reihenfolge auf Netzwerkeben egal ist
TCP da wo man auf nix verzichten kann und will.
 

Empire Phoenix

Top Contributor
UDP da wo es Sinn macht auf einzelne Pakete verzichten zu können und wo einem die Reihenfolge auf Netzwerkeben egal ist
TCP da wo man auf nix verzichten kann und will.

Jo das ist wohl die kürzeste ein eindeutigste formulierung.
 

Kr0e

Gesperrter Benutzer
"Nebenbei kann das gleiche mit UDP auch passieren. Da hast du aber nicht allein das problem dass der Entwickler zu doof war keine Bugs einzubauen, nein. Da musst du dich in der Tat noch um CRC kümmern. Denn einfach so ungesehen jedes ankommende Paket so anzunehmen ist da u.U. gefährlich. Könnte ja ein Bitfehler drin sein der die ganze Programmlogik kippt...."

Wikipedia:
"IP löscht Pakete etwa bei Übertragungsfehlern oder bei Überlast."

Sicher, dass UDP das nicht selbst regelt, in Form von gedropped Paketen ?
 

Raziell

Bekanntes Mitglied
Achso ich hätte da noch eine Frage und zwar gibt es ja verschiedene
Möglichkeiten, dass Senden von Daten im Stream zu realisieren.
Soweit ich weiss nämlich die Klassen PrintWriter, OutputStreamWriter und OutputStream.
Meine Frage wäre jetzt, welche Klasse bzw. welche Methode am besten geeignet ist?

Momentan mach ich es mit dem OutputStream:

Java:
	public void sendDates(String daten) {
		try {
			outstream.write((daten).getBytes());
			outstream.write('\n');
			outstream.flush();
		} catch (IOException e) {

		}
	}

Das gleiche auch beim Einlesen der Daten. Momentan realisiere ich es so:

Java:
private BufferedReader br = null;
br = socket.getBufferedReader();
inputString = br.readLine();

Kann ich das ganze so lassen oder gibt es bessere Alternativen?

Grüße
 

Empire Phoenix

Top Contributor
Dataoutput stream, nimmt alle primitives an, alternativ langsamer dafür mehr funktion objectoutputstream. (Oder ein eigenes Serialisiendes Protokoll, was normalerweise erheblich schneller ist als das standart. Am rande sei noch auf JGN hinzuweise das den meisten Krams bereits dabei hat, mag ich persöhnlich nicht, aber andere kommen damit gut klar.
 

Sanix

Top Contributor
Sehr interessante Diskussion, genau das was ich schon eine Zeit lang gesucht habe!
Ich habe ein bisschen im Netz gesucht bezüglich der Synchronisation.

Leider fand ich keine Beispiele, sondern nur Konzepte aber nicht wie man diese umsetzt.

Wie würdet ihr ein 2D Multiplayerspiel umsetzen mit z.B. Panzern welche aufeinander schiessen können (also ist eine exakte Synchronisation richtig, sonst verfehlen die Schüsse).

Ein Ansatz war ja in einem festen Intervall die Position zu senden und die Aktion und der Client berechnet sich selber, dies würde etwa so aussehen (richtig ?)

gameloop {
updateWorld(); //Alle Aktionen der einzelnen Actors werden ausgeführt
drawWorld();
warteBisMaxFPSerreicht();
}

Ein weiterer Thread, sendet nun z.B. alle 30ms die akutelle Position und die derzeitige Aktion (vorwärts, seitwärts, halten, ...)

updateWorld() schaut nun nach, ob ein Positionsobjekt für die Remote Actors in z.B. einer Queue ist und setzt die Position entsprechend. Falls keines vorhanden ist (z.B. wegen Lags), wird einfach die letzte Aktion nochmals duchgeführt.
Dies könnte zu sprüngen bei den Actors führen, da es ja sein kann, dass ein Lag von 200ms existiert, der Figur die Richtung gewechselt hat aber während diesen 200ms die Figur in eine andere verschoben wurde (das Problem, was schonmal in diesem Thread bemerkt wurde).

Könnte man dies etwa so umsetzen? Oder habe ich diesen Ansatz falsch verstanden?

Interessant wären hier nun auch die Verwantwortlichkeiten, wer bestimmt, ob ein Actor von einer Kugel getroffen wurde, da nicht alles synchron ist.
 

Empire Phoenix

Top Contributor
Schüsse würde ich auf den Server berechnen, das ist zwar auch wegen latenzen nicht 100% fair, aber wenigstens haste dann nur eine eindeutige sicht der welt, die den anderen Clients dann aufgezwungen wird.
 

Raziell

Bekanntes Mitglied
Dataoutput stream, nimmt alle primitives an, alternativ langsamer dafür mehr funktion objectoutputstream. (Oder ein eigenes Serialisiendes Protokoll, was normalerweise erheblich schneller ist als das standart.

Ich hab nur leider keine Ahnung wie ich sowas umsetzen könnte :oops:

Würde es denn in Ordnung sein beim OutputStream zu bleiben?
Oder macht es evtl. Sinn, den PrintWriter zu verwenden?

Gruß
 

Sanix

Top Contributor
Nochmals eine Frage zur Synchronisation:

Annahme: Der Delay zwischen Client und Server ist 50ms

Also von Client A -> Server -> Client B 100ms

Client A bewegt sich, neue Position x1, y1; Richtung r1

Client B führt diese mit 100ms Verzögerung aus und wiederholt diese Aktion bis ein neues Paket kommt. Also sagen wir 3x.

Position ist jetzt auf x1+3,y1+3; Richtung r1

Client A macht immer noch das gleiche und sendet wieder ein Update mit
neue Position x2, y2; Richtung r1

Bis dies beim Client B ist, bei welchem nun die Figur synchron zu A wäre (da einfach die letzte Aktion immer wiederholt wurde), setzt die Figur aber wieder zurück, da das Paket schon 100ms alt ist und somit eine ältere Position enthält.

Ich weiss nicht ob ich dies verständlich ausgedrückt habe.

Wie kann man dieses Problem lösen?
 

Empire Phoenix

Top Contributor
Hm jain, du übersiehst das die alte aktion auch schon 100ms alt ist, im prinzip zeigst du alles um 100ms verzögert an.
Interessanter wird es erst wenn der ping schwankt, dann hilft nur noch schönrechnen, sprich interpolieren.
 

Sanix

Top Contributor
Dies trifft aber nur auf Remote Actors zu, sprich der lokale hat keinen Delay. Dies würde es aber verunmöglichen korrekt zu zielen oder?
In der "Realität" wären z.B. beide Actors of der gleichen Linie, angezeigt wird aber der jeweilige Remote Actor hinter dieser Linie wegen 100ms delay. Da gibt es sicher auch Ansätze um dies zu lösen?
 

Empire Phoenix

Top Contributor
jo, du kannst die hitboxen im verhältnis zum ping zurückrechnen... Finde ich persönlich aber als eher nervig. Oder du machst halt gar nichts , dann müssen leute mit schlechter verbindung etwas vorhalten.

Wenn du das clientseitig berechnest haste 1 mal cheater probleme und 2. inkonsistente zustände (client a sagt ich habe getroffen, client b sagt haste nicht war schon hinter mauer, wer hat recht?)
 

Sanix

Top Contributor
Hast du das schon mal ausprogrammiert?
Habe nochmals ein bisschen das CSS Prinzip gelesen.

Mit dem berechnen der Treffer auf dem Server stimme ich dir zu. Weiter wegen der Synchronisation könnte man ja Anfangs die Zeit synchronisieren zwischen Server und Clients, also der Server gibt seine Zeit vor.
Die Packet erhalten immer einen TimeStamp. Dann wissen die anderen Clients beim erhalt eines Pakets, dass z.b. bei 100ms Delay dieses Packet 3 Ticks alt ist und berechnen von dieser Position die 3 Ticks und vergleichen mit der derzeiten lokalen Person, die abweichen kann.
Tönt leider ein bisschen ressourcenintensiv wäre wohl aber sicher auch interessant.
 

Empire Phoenix

Top Contributor
kling nach dem lustigen cs unsinn, auf einigen servern ist das compensieren zu hoch eingestellt->
P90 kaufen 5 downloads starten das der ping in die 1000 geht, innen gang mit gegnern mit dauerfeuer laufen -> jeder der sich dort irgentwann die letzte sekunde befand bekommt nen insta headshot(wird ja zurückgerechnet)

Haste auch wieder inkonsistenz:
Was macht der server wenn ein schussbefehl eintrifft auf t-100, um t, also 100ms ping, der spielera ber um t-5 von einem anderen getötet wurde der einen besseren ping hat aber erst um t-20 geschossen, wer gewinnt dann?

Geweinnt dann der der zuerst gesc hosen hat? Oder der der zuletzt getroffen wurde? Wie verhinderst du ping cheater wie im obigen beispiel?

Btw, wenn man statt instahit, echt fliegende geschosse hat, hat man tatsächkllich dutzende probleme weniger bei sowas, weil die leute sowieso vorhalten müssen, du die geschosse schnell ams erver um den ping schnller berechnen kannst die ersten ticks, sprichch startet hatl mit 1200m/s und fliegt dann mit 1000,/s weiter, und in obiger situation würden sich beide gegenseitig erschissen dann, kann ja in echt auch vorkommen.
 
M

Mc Noise

Gast
Hab da nochmal ne Frage bezüglich Tcp und Udp. Und zwar wenn Tcp ausreicht für Audio, wieso benutzt dann Skype z.B. Udp oder wieso benutzt auch RTP als Basis Udp?
 

Michael...

Top Contributor
UDP ist ein bisschen schlanker als TCP. Wenn bei TCP ein Datenpaket fehlerhaft übermittelt wird, wird es erneut angefordert, bei UDP ist es wurscht. Bei Skype kommt es ja nicht auf die Sprachqualität, sondern auf eine minimale Verzögerung an. Ein Kontrollmechanismus wie in TCP würde durch die grössere zu übertragende Datenmenge und eventuelle wiederholt angeforderte Datenpakete so ein Audiosignal nur unnötig ausbremsen. Und das RT in RTP steht ja für real time und wird für Multimediaübertragungen benutzt.
 
M

Mc Noise

Gast
Ja schon, aber die erste Seite geht eben darum, dass Tcp für sowas auch geeignet ist. Darum die Frage^^
 

Michael...

Top Contributor
Ja schon, aber die erste Seite geht eben darum, dass Tcp für sowas auch geeignet ist. Darum die Frage^^
Geeignet vielleicht schon, stellt sich nur die Frage ob notwenig. Man kann einen Brief per Einschreiben mit Rückantwort verschicken - man ist sicher, dass er ankommt, kostet aber mehr. Wenn's der Brief an die Oma ist, ist aber vielleicht gar nicht schlimm wenn er mal nicht ankommt.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
S UDP DatagrammSocket Netzwerkprogrammierung 4

Ähnliche Java Themen

Neue Themen


Oben