# Java Game Network Engine



## Kr0e (14. Feb 2011)

Hallo Zusammen,

nach einem langen Auslandsaufenthalt, bin ich nun wieder zurückgekehrt mit vielen neuen Ideen.
Mir schwirrt schon lange der Wunsch einer Engine extra für Netzwerk Multiplayerspiele im Kopf rum.

Gelesen habe ich dies bezüglich schon recht viel und habe schonmal 
ein paar feste Ideen aber auch ein paar Fragen sind geblieben:


TCP oder UDP ?

Diese Frage ist natürlich die wichtigste. Gelesen habe ich, dass für ein solches Vorhaben UDP gegenüber TCP überlegen ist,
undzwar in der Hinsicht, dass es z.B. verlorene Pakete nachschickt und dadurch alle Clienten lansamer werden.

Quelle: Game Development Tutorials – Game Networking – UDP vs. TCP


Übermittlung der Koordinaten/Änderungen/Sonstige:

Zu dem Thema hab ich mir den Wikiartikel zur Sourceengine durchgelesen und war recht überrascht, wieviele Tricks
dort angewendet werden, um das Spielen derart angenehm zu machen. Stichworte wären Movement Prediction und
Latency Compensation.

Aber meine erste Idee war eigentlich eine ganz andere: Die Clienten wissen Sachen wie Geschwindigkeit, Rotationsgeschwindigkeit
und Position, um praktisch alle notwendigen Schritte selbst zu berechnen. Damit die Clienten nicht aus dem Takt geraten, dachte ich daran, vom Server alle 25 ms ein Signal zu schicken, dass jeden Clienten auffordert einen Rechenschritt durchzuführen.
Dies könnte (müsste) dann über TCP geregelt werden. Änderungen von anderen Spielern werden dann bei diesem 
25ms Update ggf. an die Clienten mitgesendet.

Allerdings wären dann wieder 2 Probleme existent:

-Wenn ich eine Änderung vornehme als Client (Z.B. ein Schuss...) dann würde dieser verzögert geschehen. Was für das Spielverhalten grottig ist. Sprich auch dann müsste ich etwas ähnliches wie Movement Prediction impl.

-Ich MUSS davon ausgehen können, dass Floatoperationen auf allen PCs exakt gleichausgeführt werden. Nur dann, kann ich dem
Client die Aufgabe geben, alles selbst zu berechnen, was natürlich auch den Server erheblich entlasten würde.

=> An dieser Stelle eine wichtige Frage:  Ist das bei Java garantiert ?? Ich weiß, dass das bei C/C++ Plattform- und Kompilerabhängig ist, wodurch dies nicht möglich wäre mit den "alten" Sprachen. Meine Hoffnungs ist, dass durch das
Prinzip der virtuellen Maschiene dies garantiert ist. Andererseits ist die JVM ja auch nur in C oder was auch immer geschrieben und
diese wiederum beuntzt ja die Prozessor-internen Befehle für die Standard Operationen. Vlt. könnt ihr da etwas Licht ins dunkel bringen 

Gruß,

Chris


----------



## tuxedo (14. Feb 2011)

Kr0e hat gesagt.:


> Diese Frage ist natürlich die wichtigste. Gelesen habe ich, dass für ein solches Vorhaben UDP gegenüber TCP überlegen ist,
> undzwar in der Hinsicht, dass es z.B. verlorene Pakete nachschickt und dadurch alle Clienten lansamer werden.
> 
> Quelle: Game Development Tutorials – Game Networking – UDP vs. TCP



Ohne deinen Beitrag  bis zum ende gelsen zu haben, und ohne den Link geöffnet zu haben:

UDP schickt keine Pakete nach. Geht eins verloren, ist es weg. Nach "nachsenden" muss auf Protokollebene selbst erkannt und gehandhabt werden.

- Alex

[update]

Zitat aus dem Artikel:



> UDP is an unreliable protocol. In practice, most packets that are sent will get through, but *you’ll usually have around 1-5% packet loss, and occasionally you’ll get periods where no packets get through at all* (remember that there are lots of computers between you and your destination where things can go wrong…)



Und weiter:



> Finally, although UDP doesn’t do much on top of IP, it does make one guarantee for you. If you send a packet, it will either arrive in whole at the destination, or not arrive at all. *So if you send a 256 byte packet to another computer, that computer cannot receive just the first 100 bytes of the packet, it must get the full 256 bytes of data. This is pretty much the only guarantee you get with UDP, everything else is up to you!*


----------



## tuxedo (14. Feb 2011)

Ah, jetzt ja. Du hast dich etwas umständlich ausgedrückt. "UDP ist TCP überlegen, eben weil keine Pakete nachgesendet werden." So in der Art hättest du's schreiben sollen. 

Aber gut, *back to topic*

Wenn du die Last vom Server nehmen willst, um diese "allmächtigen Berechungen" direkt beim Client auszuführen: Was ist dann mit dem erhöhten Datenaufkommen am Server? Der Server muss 

a) schauen dass die Clients synchron arbeiten
b) die Berechneten Daten der Clients sammeln und an die anderen Clients weiterleiten.

Ohne es ausprobiert zu haben: Ich kann mir nicht vorstellen dass die Berechungen so CPU intensiv sind, dass man das besser beim Client berechnet und damit weitere Paketlaufzeiten aufsummieren lässt,die man dann auf Serverseite wieder rausrechnen muss.

Der Artikel schreibt ja recht schön, dass es in Echtzeitspielen auf Millisekunden ankommt. Und wenn Daten erst 3-mal im Kreis rumgeschickt werden müssen, dann tut das dem Echtzeitverhalten des Spiels nicht gut.

Ergo: Besser am Server die Berechnung durchführen und mehr Kohle für eine schnellere CPU ausgeben. Dadurch spart man sich mind. eine Übertragung der Daten. 

- Alex


----------



## Landei (14. Feb 2011)

Du willst also das Rad neu erfinden?

jgn - Project Hosting on Google Code

Project Darkstar


----------



## Kr0e (14. Feb 2011)

@Landei:

Falsch! Hier wird nix 2mal erfunden. Es geht um eine komplette Engine. Nich bloss wie Darkstar ein API für einfachere Kommunikation mit vielen Clienten (Genau das ist RedDwarf (Darkstart gibts nicht mehr)) und jgn ist wie der Autor über sein eigenes Projekt schreibt: Light-Weight. Zitat: An extremely light-weight framework for game networking in Java. Beide Frameworks bieten einem eine gute Unterstützung an, wenn es um Netzwerkprogrammierung für Spiele geht. Aber um jetzt als Beispiel mal wieder die Source Engine aufzulisten (Jetzt nur der Netzwerkteil, nicht Grafik + Physik): Dort werden allerhand Methoden implementiert um z.B. viele Clienten mit unterschiedlicher Netzwerkanbindung alle auf dem gleichen Stand zu halten.

Genau genommen erfindet RedDwarf das Rad zum Teil etwas neu: Anstatt eine gute SOcket/Nio Library zu benutzen, schreiben die sich das selbst, obwohl es bereits extremst gute Frameworks zu diesen thema gibt. Netty3 oder Apache Mina zum Beispiel.

@Tuxedo:

Ja, tut mir Leid, hab da ein Wort oben im Satz vergessen, wodurch der Sinn flöten ging .
Dein leichter Sarkasmus anspielend auf die allmächtigen Berechnungen ist zwar richtig, aber das war nicht genau das was ich meinte. Ich meinte den Server entlasten, da dieser nicht mehr soviele Daten verschicken muss.

Also quasi ob es möglich ist, dass die Clienten die Bewegungen der Objekte selbst berechnen, damit der Server weniger Daten pro Client versenden muss und damit mehr Clienten bedienen könnte. Von der CPU des Servers hab ich garnicht geredet ?! 

Diese Idee setzt halt voraus, dass Floatoperationen 100% gleich laufen überall. Und das UDP bei Echtzeitspielen überlegen ist, meinte ich damit (Wie du ja auch geschrieben hast), dass eben alte Pakete, die verloren gehen eh in 50 ms wieder veraltet sind und es von daher nicht allzuviel ausmacht. TCP würde dann nachschicken etc, was dann natürlic hschlecht wäre.

In einem Bericht habe ich auch gelesen, dass wenn man wohl TCP und UDP (Das fand ich iwie merkwürdig und hinterfrage das persönlich auch noch ) nicht zusammen verwenden soll, da durch TCP der UDP Paketverlust begünstigt wird, aber keine 
Ahnung inwiefern das stimmt.
Link: Characteristics of UDP Packet Loss: Effect of TCP Traffic

Gruß,

Chris


----------



## tuxedo (14. Feb 2011)

> Ja, tut mir Leid, hab da ein Wort oben im Satz vergessen, wodurch der Sinn flöten ging .
> Dein leichter Sarkasmus anspielend auf die allmächtigen Berechnungen ist zwar richtig, aber das war nicht genau das was ich meinte. Ich meinte den Server entlasten, da dieser nicht mehr soviele Daten verschicken muss.



Okay, du beziehst dich also auf die Netzlast und nicht auf CPU. Okay. Wieviel kbyte/sek produziert denn ein rasanter Action-Shooter pro Client? Hab da echt 0 plan. Kann da nur raten. 
ich schätze mal einfach so ins blaue: 10kbyte/sek (vermute mal dass das noch immer recht viel ist). Dann wären wir bei einem Server der mit 100MBit angebunden ist bei rund 1000 Clients. 

Unter der vorraussetzung dass meine Schätzung einigermaßen realistisch ist stellt sich einem die Frage: Beherrschen die bekannten Echtzeitspiele-Server wegen der CPU Last die 1000 Clients nicht, oder ist es die Art von Spiel die 1000 Clients nicht unterstützt (weil es wenig Sinn machen würde?)?
Oder anders gefragt: Gibts Echtzeit-Gameserver Implementierungen die mehr als 1000 Spieler beherbergen können? Ich mein: Server im Sinne von "Eine Brocklen Hardware der für ein Spiel zuständig ist", und nicht im Sinne von: "Ach, wir haben hier eine 'Gamserver-Cloud' mit loadbalancer etc. pipapo."



> Also quasi ob es möglich ist, dass die Clienten die Bewegungen der Objekte selbst berechnen, damit der Server weniger Daten pro Client versenden muss und damit mehr Clienten bedienen könnte. Von der CPU des Servers hab ich garnicht geredet ?!



Ach so: Nicht jeder Client soll basierend auf seiner Handlung seine Daten berechnen, sondern der Server schickt auch gleich noch die Basisdaten anderer Clients, so dass er nicht nur seine hat, sondern auch die der anderen? Wäre dann die ganze Berechnung nicht "redundant" da jeder (oder viele) Clients die gleichen Daten zur Berechnung bekommen und im optimalfall auch gleiche Ergebnisse produzieren?


Sehe da bis jetzt noch nicht das Potential dass der Server da Traffik spart....

_Dein Vorgehen: Clients rechnen alle selbst:_
Die Clients schicken ihre eigenen Basisdaten zum Server, der sie dann weiter an die anderen Clients schickt.

_Bisheriges Vorgehen: Server rechnet alles selbst:_
Die Clients schicken ihre eigenen Basisdaten zum Server, der führt die Berechnungen durch und schickt das Ergebnis an alle Clients. 


Sieht für mich traffik- und latenztechnisch gleich aus. Mit dem einen Unterschied: Dein Verfahren bedarf noch eines einheitlichen Zeitsignals bei allen Clients. Sonst laufen die ja alle asynchron. Und das Zeitsignal erfodert auch wieder weiteren Traffik und letztendlich auch weitere Latenzen (synchronisierung über's Netzwerk hinweg kostet halt Zeit).



> Und das UDP bei Echtzeitspielen überlegen ist, meinte ich damit (Wie du ja auch geschrieben hast), dass eben alte Pakete, die verloren gehen eh in 50 ms wieder veraltet sind und es von daher nicht allzuviel ausmacht. TCP würde dann nachschicken etc, was dann natürlic hschlecht wäre.



FullACK ... Kommt halt stark auf den Einsatzzweck an. In diesem Fall punktet UDP ganz klar.



> In einem Bericht habe ich auch gelesen, dass wenn man wohl TCP und UDP (Das fand ich iwie merkwürdig und hinterfrage das persönlich auch noch ) nicht zusammen verwenden soll, da durch TCP der UDP Paketverlust begünstigt wird, aber keine
> Ahnung inwiefern das stimmt.



Hui. Kann das auch nicht so ganz glauben. Würde da aber eher auf einen Schlechten TCP/IP Stack setzen. Denn was wie im Internet mit welchem Protokoll wohin übertragen wird, kann man halt nicht beeinflussen. Von daher: Was soll man mit diesem Statement anfangen? 
Wir haben hier ein Gigabit-Videonetzwerk mit dutzenden Multicast und auch Unicast-Streams. Wenn da die TCP Unicast-Verbindungen die UDP Multicast-Verbindungen negativ beeinflussen würden, dann sollten das unsere IT Spezis auf ihren zahlreichen cisco managed switches schon festgestellt haben. Aber mir ist von solchen Problemen nix bekannt. Aber vielleicht enthüllt der Artikel das Geheimnis ja --> *lesen geh*


----------



## Kr0e (14. Feb 2011)

Hi Tuxedo, danke für die Antwort!

Da der Server in meinem Szenario nur die Änderungen schicken würde, gäbe es quasi sehr viel weniger Traffic. Nur das Zeitsignal
im allerbesten Fall. Aber ich gebe dir Recht, dass im Worstcase wenn jeder Client andauernd was ändert vlt. dieses Modell versagen würde. Andererseits alle 33 ms alle wichtigen Daten von jedem Clienten an jeden anderen Clienten zu übertragen erscheint mir (auch wenn das die gängige Methode ist zur Zeit) iwie etwas verbesserungswürdig.

Ich sag mal so: Wenn jeder Client pro Sekunde vlt. 5 Änderungen machen würde (Einfach nur fiktiv mal angenommen (Ein Schuss, 4 Movementbefehle)) dann wären das weniger Daten als alle 25 ms (40 x pro Sekunde) an jeden Clienten die Position aller Clienten zu schicken. So mein ich das...


----------



## tuxedo (14. Feb 2011)

Ich steig nicht ganz durch:



> Da der Server in meinem Szenario nur die Änderungen schicken würde, gäbe es quasi sehr viel weniger Traffic. Nur das Zeitsignal



Na irgendwo her müssen die Basisdaten ja kommen -> Client. Ein Client schießt und macht 4 Bewegungen. Ergo schickt er 5 Datensätze an den Server.

Wenn nun die Clients rechnen, und nicht der Server, kann der Server ja kein Delta bilden und muss alles an alle Clients weiterreichen. Ergo: 5 Datensätze vom Client zum Server plus X mal 5 Datensätze zu den verbundenen Clients PLUS Zeitsync-Signal. Macht 5 + (x  * 5) zu übertragende Datensätze + Zeitsync-Signal

Wenn aber der Server, und nicht die Clients rechnen, dann kann der Server ein Delta bilden und nur die Änderungen weiterleiten. Ergo: Wieder 5 Datensätze vom Client zum Server plus X mal 'nur noch deltas'. Im Worstcase bist du dann auch wieder bei 5 + (x*5), im optimalfall halt weniger. Sparst dir aber den Zeitsync (eventuell)



> Andererseits alle 33 ms alle wichtigen Daten von jedem Clienten an jeden anderen Clienten zu übertragen erscheint mir (auch wenn das die gängige Methode ist zur Zeit) iwie etwas verbesserungswürdig.



Client zum Client? P2P? Öhm, ist es nicht "sicherer" den Server dazwischen zu schalten? Der hat i.d.R. mehr Bandbreite um viele Daten zu verschicken.

Aber nochmal was anderes:

Du kennst Teamspeak? Du weiß dass auch hier Echtzeit gefragt ist? Gut, TS nutzt auch UDP, von daher ist das nicht das "Problem". Aber die Netzwerklast ist absolut vernachlässigbar. 

In TS2 bei bestmöglicher Qualität braucht ein Sprecher rund 3,5KByte/sek. Der Server empfängt also 3,5kbyte/sek und sendet das ganze x-fach (eben für jeden Raumteilnehmer) wieder raus. 

Selbst große TS Server mit seehr vielen Räumen und seeehr vielen gleichzeitigen Sprechern ist die Bandbreite NIE ein Problem. 
Für einen Seitenast meiner Diplomarbeit hab ich Messungen eines großens, vielbesuchten öffentlichen TS Servers gemacht. Hab eine Woche lang gemessen wieviele Teilnehmer online sind und welchen Traffik der Server gerade verursacht. Anschließend hab ich hochgerechnet. Erst bei > 17.000 Teilnehmern geht dem Server die Bandbreite aus. 

Okay, das mag jetzt nicht direkt mit einem Echtzeit-Gameserver vergleichbar sein. Denn da muss der Server nicht nur die Daten "Relais-Artig" weiterschicken, sondern im Normalfall auch noch Dinge berechnen. Aber ich denke der Traffik könnte sehr ähnlich ausfallen. Insofern hab ich etwas bedenken mit deinem Ansatz.

Ich habe so die Vermutung dass du versuchst ein Problem zu optimieren, das gar kein reales Problem ist. 
Was ich bis jetzt von Gameservern sagen kann: Die CPU sowie der RAM ist ein Limit das es ggf. zu optimieren gilt. Okay, ob RAM bedarf bei Shootern serverseitig ein Thema ist weiß ich nicht. Aber von Netzwerk-Last Problemen hab ich noch nichts gehört (was nicht unbedingt was heissen mag).


----------



## Empire Phoenix (14. Feb 2011)

Ram ist eigentlich egal, da man keient exturen/sounds ect hat. CPu ist was ganz anderes die ist so zimelich das wichtigste. Wobei netzwerk kann bei nicht gut optimierten netzwerkcode sehr schnell ausgehen. In der praxis benutze ich für meine Sachen eine UDp verbindung für unwichtige daten und eine TCP verbindung für wichtige.

UDP -> positionsupdates der player, wenn mal enes fehlt ist es egal das nächste ist eh schon auf dem weg
TCP -> logindaten, da diese den server umbedignt erreichen müssen.


----------



## despikyxd (14. Feb 2011)

habt ihr bei UDP auch mal and das PASSTHROUGH an den routern der clients gedacht ?

wie ich sehe : NEIN

es ist kein problem als client hinter einem oder mehreren routern ein udp-paket an ein festes ziel zu senden ...
aber wie soll die antwort die an den router gesendet wird von diesem zum rechner gelangen ?
der server kennt als remote-ip nur die jenige des routers der das home-lan mit dem internet verbindet ...
und ohne richtiges UDP-NAT weis der router dann nicht was er mit der antwort anfangen soll und verwirft sie einfach ...

ergo : du müsstest erstmal ein lauffähiges UDP-NAT-PASSTHROUGH entwickeln ... valve hat das in der GoldSrc Engine *HL1* schon mal geschafft ... 1998 ... und damit wars natürlich n leichtes das auf Source stand 2004 zu bringen ...
und das müsstest du jetzt auch erstmal schaffen ... viel spaß dabei ...

und genau aus diesem grund punktet bei solche hobby-projekten eindeutig TCP ... da TCP eine HOST-TO-HOST verbindung herstellt womit die problem an routern wegfallen ...
oder wollt ihr mir alle erzählen ihr seit alle so wahnsinnig und geht ohne einen router mit hardwarefirewall ins netz ? ... wenn ja : heult nicht rum wenn ihr mal gehakt werdet ... eure eigene schuld

also denkt mal bei sowas auch in zukunft über solche eigenschaften von protokollen nach ... und nicht nur das was ab schicht 4 damit passiert


----------



## Kr0e (15. Feb 2011)

Dafür gibt es Ports du Genie, nie was von UDP Hole Punching gehört, wa ?


----------



## despikyxd (15. Feb 2011)

das mit dem genie geht erstmal zurück ...
ports wurden nicht für NAT traversal erfunden du superhirn ... sondern um einem host die möglichkeit mehrerer gleichzeitiger verbindungen zu haben ...
und UDP hole punching ist hier im zusammenhang lediglich eine sehr oft genutze implementierung des abstrakten NAT PASSTHROUGH
es ist eigentlich nichts weiter als das übertragen von TCP-NAT-Tabellen in den UDP bereich ...
wobei es DEUTLICH bei wikipedia steht das UDP hole punching kein standardisiertes verfahren ist und daher nicht von einem NAT unterstütz werden muss ...
ich hatte auch mal n router der dieses udp hole punching einfach nicht konnte ... online-zocken war damit bei udp-basierten spielen unmöglich ... musste mir extra n neuen router holen damit es dann ging ...
wie gesagt ... es ist EINE möglichkeit ... aber nicht DIE möglichkeit ...

btw : wenn du schon solches wissen hast warum fragst du UNS dann ob TCP oder UDP ? du kennst die lösung doch schon ...


----------



## tuxedo (15. Feb 2011)

Kann despikyxd da fast zu 100% zustimmen.

@EmpirePhoenix
Bzgl. des RAMs... Gut, Texturen gibts auf dem Server nicht. Aber je nach Spiel jede Menge Objekte, große Maps, ... Bei MMORPG Servern ist der RAM definitiv ein Thema. Bei Shootern... Keine Ahnung. "Könnte", "muss aber nicht" ...

Aber um mal zurück zum Thema TCP vs. UDP zu kommen: Alle Welt sagt ja immer: Nimm für Echtzeitpsiele UDP. Aber irgendwer schwimmt ja immer gegen den Strom. Deshalb die Frage: Kennt jemand ein Game das hier trotz aller Warnungen TCP statt UDP benutzt? 

Ich mein, die ganzen Nachteile von TCP die hier immer wieder aufgeführt werden sind doch im wesentlichen diese:

1) zu viel Protokoll-Overhead
2) zu aufwendige Fehlerkorrektur

Zu 1): Naja, im Zeitalter von Megabit-Internet-Zugängen ist das doch fast schon vernachlässigbar. 

Zu 2): Es wird hier immer vom Worst-Case ausgegangen. Ist denn eine TCP Verbindung wirklich so unzuverlässig dass es andauern und ständig zum erneuten Senden von Paketen kommt, was dann die anderen Pakete u.U. ausbremst? Praxisnahe Messungen würden mich hier mal interessieren.

- Alex

P.S. Nicht dass jetzt eienr glaubt ich würde hier TCP bevorzugen wollen. Aber man kann das Thema ja auch mal von der anderen Seite beleuchten.

[update]

Hab mal eine kleine Messung mit einem für Echtzeit-Kommunikation nicht optimal geeigneten Protokoll gemacht: SIMON.

Test-Client (1Ghz MINI ITX, 1GB RAm, Java6, Debian 5 32bit) hängt an einem DSL16.000 Anschluss, Server ist ein Root-Server (AMD Athlon 64 X2 Dual Core Processor 5600+, 2GB RAM, Debian 5  64bit) mit 100Mbit Anbindung.

Ohne dass ich irgendwas feintunen musste, komm ich auf Clientseite auf 239 Methodenaufrufe pro Sekunde (Client ruft so schnell wie es geht in einer Endlosschleife die Methode auf, ohne sleep() etc.). Und das bei einer CPU Last von 18%. 

Ein Methodenaufruf verursacht hier 119 bytes TX Traffik und 48bytes RX Traffik (groß genug um einiges an Positionsdaten zu übertragen).

239 Aufrufe/Sek entspricht etwa 4,1 Millisekunden für einen Aufruf. Selbst wenn also der Server hier einies mehr tun muss als nur den Methodenaufruf mit einem "void" zu beantworten und hier und da Pakete verloren gehen: Da darf ein Aufruf ruhig mal 5x so lange brauchen. Und selbst dann sind wir erst bei 20ms, was ja auch noch nicht sooo tragisch sein sollte.

Okay, das ist nur ein primitiver Test. Aber kann mir wer anhand dieser Zahlen ein TCP-Bottleneck aufzeigen?

Man könnte jetzt argumentieren: Ja, aber wenn die Leitung mal etwas gestört ist, dann sieht das nicht mehr so toll aus.
Gut, mag sein. Aber ob dann ein spielen über UDP noch möglich wäre ist ebenso fraglich. 

Und nochmal: Mir leuchten die Argumente für UDP ein. Aber aktuell sieht TCP für mich nicht wirklich so viel schlechter aus.


----------



## Empire Phoenix (15. Feb 2011)

Erstmal zu udp,
der router merkt sich wenna uf port x ein packet rausgeht an adresse y, wenn dann von irgetwo packete auf dem port reinkommen gibt er die weiter an den letzten entsprechenden client hinterm nat.

kommt auf die Daten an, bei tcp hat man ähnliche verluste wie bei udp nur das die ausgeglichen werden, kritischer ist hier das verhalten des neusendens. Durch die inorder heist das -> tickrate 10ms beim server, ping 100 -> 9 updates können erst verarbeitet werden wenn das 1 te was fehler hatte neugeschickt wird. -> lag, weil bis zum neusenden alle anderen datena uch nicht verarbeitet werden können.


----------



## tuxedo (15. Feb 2011)

Hmm, okay, aber wer spielt denn mit nem 100er Ping ein Echtzeit-Spiel? Da sind ja alle ganz scharf drauf nen Fastpath-Anschluss zu haben (was heutzutage jeder 16.000er Anschluss hat und man bei kleineren Anschlussen als Option dazubuchen kann). Dann liegen die Ping-Zeiten bei unter 50ms. Meist sogar bei unter 20ms. 

Gehen wir also mal von 30ms aus. Dann wäre der Lag fast nicht spürbar, oder?!

- Alex


----------



## schalentier (15. Feb 2011)

Ich glaube ein 30ms Ping ist die absolute Ausnahme, egal bei welchem Spiel. Bin nicht so der Onlinezocker, aber ich meine mich an 200er Ping bei WoW und 100ms bei nem Shooter erinnern zu koennen. Weniger ist sicherlich besser, aber mit 100ms sollte ein Spiel schon noch vernuenftig spielbar sein.

Zum Thema: Meine Empfehlung waere, fang mit ner absolut einfachen Loesung an (Server schickt alles Notwendige an alle Clients) und gugg, wie weit du damit kommst. Viel schwieriger als das reine (schnelle) Senden der Daten wird so oder so die lag correction sein.


----------



## tuxedo (15. Feb 2011)

Ping!=Ingame-Latenz


Das was dir WoW anzeigt ist die Latenz innerhalb des Spiels. Was da alles mit reingerechnet wird weiß ich nicht, ich kann's nur vermuten (z.B. Verarbeitunszeit der Spiel-Datenpakete, ...). Jedenfalls ist diese Anzeige nicht vergleichbar mit einem Ping. 

Und da hier unter anderem das Pro und Contra TCP/UDP diskutiert wird, muss man eine Ebene weiter unten ansetzen. Und das heisst: Nicht die InGame-Latenz betrachten, sondern die Latenz auf Netzwerkebene. Und da sind solche Pingzeiten von deutlich unter 100ms durchaus realistisch.


----------



## Kr0e (15. Feb 2011)

Hallo,

danke für die zalhreichen Antworten. Tuxdeo, hattest du nicht mal (kann schon wirklich ne Weile her sein... paar Monate denk ich) gesagt, dass TCP Pakete bei Routern generell "besser" behandelt werden ? Quasi im Verhältnis weniger oft verschwinden als UDP Pakete ? Wenn ja, dann würde sich vermutlcih wirklich TCP lohnen.

Ich anfangs die Befürchtung, dass langsame TCP Clienten alle Clienten langsam machen könnten... 

Mir fiel gestern dazu noch ne Lösung ein: Man könnte ja einfach Daten verschicken, dann einfach die RTT ermitteln und wenn dann ein Client mit z.B. 150 ms dabei (alle Anderen haben jetzt mal als Beispiel  30-40), dann könnte man dem 150ms Clienten einfach seltener Updates schicken. Damit alle glecih auf sind. Und diesen Test ggf. periodisch wiederholene, damit ein CLient, wenn er grad nur einfach einen Download am laufen hatte, danach wieder normal mitspielen kann. Ich werde das eifnach mal ausprobieren. Wenn es garnicht geht, was aber wahrscheinlich nicht eintreten wird, meld ich mich nochmal 

Danke soweit 


@despikyxd: Ich kenne nur das Verhalten, welches von Empire Phoenix beschrieben wurde. Was du dir da mit UDP PASSTHROUGH zusammenstückelt hab ich noch nie gehört. UDP Hole punching ist auch noch etwas anderes. Ich kenne nur dieses Verhalten. Ausgehende Verbindungen gehen beim ROuter in eine Tabelle und Antworten von der passenden Adresse gehen ohne irgendeinen umweg zum Rechner im LAN. Keine Ahnung wo da das Problem sein soll. Zeig mir mal nen Router, der das nicht packt.


----------



## tuxedo (15. Feb 2011)

> danke für die zalhreichen Antworten. Tuxdeo, hattest du nicht mal (kann schon wirklich ne Weile her sein... paar Monate denk ich) gesagt, dass TCP Pakete bei Routern generell "besser" behandelt werden ? Quasi im Verhältnis weniger oft verschwinden als UDP Pakete ? Wenn ja, dann würde sich vermutlcih wirklich TCP lohnen.



Naja, ich hab noch keinen Router gebaut und noch keine Software dafür implementiert. Aber per Definition von UDP *dürfen *Pakete "verschwinden". Und wenn der Router meint "im Stress" zu sein, dann droppt er wohl eher ein UDP Paket als ein TCP Paket. Zumindest ist das meine Annahme. 

Das kann aber von Router zu Router sicherlich variieren.



> Ich anfangs die Befürchtung, dass langsame TCP Clienten alle Clienten langsam machen könnten...



Boah, du enttäuschst mich gerade schwer... ;( Dachte du bist in Sachen NIO mittlerweile recht fit?! Wenn dem so wäre, dann wüsstest du, dass ein Client unmöglich einen anderen Client beeinflussen kann (was im übrigen auch bei normalem IO der Fall sein sollte). 
Wenn ein Client den anderen blockiert, dann nur weil sie gemeinsame Ressourcen benötigen und der eine auf den anderen warten muss. Aber das ist reine Implementierungssache und hat nix mit dem Transport via TCP zu tun.





> Mir fiel gestern dazu noch ne Lösung ein: Man könnte ja einfach Daten verschicken, dann einfach die RTT ermitteln und wenn dann ein Client mit z.B. 150 ms dabei (alle Anderen haben jetzt mal als Beispiel 30-40), dann könnte man dem 150ms Clienten einfach seltener Updates schicken. Damit alle glecih auf sind. Und diesen Test ggf. periodisch wiederholene, damit ein CLient, wenn er grad nur einfach einen Download am laufen hatte, danach wieder normal mitspielen kann. Ich werde das eifnach mal ausprobieren. Wenn es garnicht geht, was aber wahrscheinlich nicht eintreten wird, meld ich mich nochmal



Wie gesagt: Es bremsen sich bei TCP nur die Pakete innerhalb einer Socketverbindung aus. Andere Socketverbindungen (zum gleichen Server-Port) sind davon nicht betroffen. 

Ich fasse mir mich mal zusammen:

* UDP ist bei Echtzeitdingen TCP zu bevorzugen
* TCP kann, in Abhängigkeit zur Latenz (hier: eine gute Latenz), genauso gut sein wie UDP mit einer schlechten Latenz. 
* Wenn die Verbindung gut ist (wenige bis keine Paketverluste), könnte man ebenso TCP nehmen
* Ich hab noch keine Doku oder Messung dazu gefunden wieviele TCP Pakete "pi mal daumen" im Vergleich zu UDP verloren gehen.

- Alex


----------



## Empire Phoenix (15. Feb 2011)

Naja zum ping also finde mich gerade leicht diskriminiert, stell dir vor es gibt leue die NICHT einen mage 16000 fastpath haben, diese generell auszugrenzen macht wenig sinn und verringert potenzielle Kunden/Spieler.

Und das udp gedroppt wird ist ganz praktisch wenn man über udp nur unwichtges verschickt und der rest über txp, weil dann kurzzeitige lastspitzen ohne extra behandlung gelöst werden.


----------



## tuxedo (15. Feb 2011)

Empire Phoenix hat gesagt.:


> Naja zum ping also finde mich gerade leicht diskriminiert, stell dir vor es gibt leue die NICHT einen mage 16000 fastpath haben, diese generell auszugrenzen macht wenig sinn und verringert potenzielle Kunden/Spieler.



Naja, hatte auch nicht immer DSL16.000. Für DSL6000 hatte (oder hat noch) die Telekom ne Zusatzoption im Angebot mit der man FastPath bekommen konnte. Waren glaub irgendwas um zusätzliche 1,50EUR/Monat...

Natürlich ist es quatsch zu sagen: Jupp, weg mit UDP. Wir nehmen TCP weil wir nur FastPath User haben und uns den UDP Aufwand sparen wollen.
Aber es zeigt trotzdem recht deutlich wohin die Reise geht ;-)



> Und das udp gedroppt wird ist ganz praktisch wenn man über udp nur unwichtges verschickt und der rest über txp, weil dann kurzzeitige lastspitzen ohne extra behandlung gelöst werden.



Klar. Da wo man auf 100,00%ige Zuverlässigkeit verzichten kann wäre es quatsch TCP einzusetzen. Ein Datagram ist programmiertechnisch auch schneller versendet und empfangen als jetzt "groß" eine TCP Verbindung aufzusetzen und mit Streams eine wenige byte große Nachricht zu versenden und danach die Verbindung wieder aufzuräumen ;-)

UDP hat nach wie vor die Nase vorn. Aber TCP hat dank der rasanten Entwicklung und Fortschritten bei der Internetanbinding schonmal den Blinker links gesetzt ...


----------



## Kr0e (15. Feb 2011)

Wollte keinen enttäuschen  Ich drück mich vlt öfters ungünstig aus. Liegt evt. daran, dass ich nen halbes Jahr kaum Deutsch geredet hab, sondern Englisch. Wenn ich das mit dem Zeitinterval amchen würde, müsste ich ja warten bis jeder Client das Zeitsignal bekommen hat. Angenommen ein Client ist wirklich langsam (300ms, ja man könnte jetzt die Frage stellen, ob der überhaupt mitspielen darf ) und alle anderen super schnell, wenn ich nun asynch. an jeden einzeln das Signal schicke, Könnte es passieren, dass beim super langsamen sich ne Warteschlange an alten Zeitsignalen ansammelt. Und daher würde ich in diesem Fall warten, bis jeder Writeaufruf  wirklich geschehen ist. Das wäre dann ggf. auch ohne das Zeitsignal so.. Also 30x pro Sekunde die Koordinaten schicken würde evt. beim langsamen Clienten dann eine Warteschlange verursachen.

Nun nochmal kurz was zum Senden: Mit NIO kann man doch nicht asynchron senden, man kann doch lediglich sich anzeigen lassen, ob ein Socket beschreibbar ist oder nicht (Gleiches für das Lesen von Sockets). Dennoch würde jeder write-Aufruf solange blockieren (Also ich meine jetzt innerhalb eines Frameworks. Klar Netty und Mina sind Eventdriven, als Programmierer bekommt man Futures, aber intern sind die Workerthreads beteiligt und warten dann bei jedem write solange, bis der Kram wirklich versendet wurde, oder nicht ?)

Sprich wenn man einfach ohne Ende Writerequests reinkloppt und die Verbindung zum Clienten agrnicht in der Lage ist, dass entsprechend schnell zu transportieren, so würde die Warteschlang des Frameworks immer länger werden. Von daher sollte man doch warten, dass jeder Write request fertig ist. Und halt genau in diesem Fall würde der langsame alle anderen ausbremsen.
Sofern man dann natürlich nicht dem langsamen Clienten weniger Pakete schickt. Also vlt nur alle 80 ms statt alle 30ms.
Dann wäre das Problem wieder beseitigt.

ICh hoffe ich habe das diesmal etwas konkreter erklärt.

Gruß,

Chris


----------



## tuxedo (15. Feb 2011)

Kr0e hat gesagt.:


> Wollte keinen enttäuschen  Ich drück mich vlt öfters ungünstig aus. Liegt evt. daran, dass ich nen halbes Jahr kaum Deutsch geredet hab, sondern Englisch.



Ja, das kann durchaus sein. Nach meinem halben Jahr Indien gings mir wohl ähnlich.



> Wenn ich das mit dem Zeitinterval amchen würde, müsste ich ja warten bis jeder Client das Zeitsignal bekommen hat. Angenommen ein Client ist wirklich langsam (300ms, ja man könnte jetzt die Frage stellen, ob der überhaupt mitspielen darf ) und alle anderen super schnell, wenn ich nun asynch. an jeden einzeln das Signal schicke, Könnte es passieren, dass beim super langsamen sich ne Warteschlange an alten Zeitsignalen ansammelt. Und daher würde ich in diesem Fall warten, bis jeder Writeaufruf  wirklich geschehen ist. Das wäre dann ggf. auch ohne das Zeitsignal so.. Also 30x pro Sekunde die Koordinaten schicken würde evt. beim langsamen Clienten dann eine Warteschlange verursachen.



Und genau in so einem Fall macht UDP wieder Sinn.




> Nun nochmal kurz was zum Senden: Mit NIO kann man doch nicht asynchron senden, man kann doch lediglich sich anzeigen lassen, ob ein Socket beschreibbar ist oder nicht (Gleiches für das Lesen von Sockets). Dennoch würde jeder write-Aufruf solange blockieren (Also ich meine jetzt innerhalb eines Frameworks. Klar Netty und Mina sind Eventdriven, als Programmierer bekommt man Futures, aber intern sind die Workerthreads beteiligt und warten dann bei jedem write solange, bis der Kram wirklich versendet wurde, oder nicht ?)
> 
> Sprich wenn man einfach ohne Ende Writerequests reinkloppt und die Verbindung zum Clienten agrnicht in der Lage ist, dass entsprechend schnell zu transportieren, so würde die Warteschlang des Frameworks immer länger werden. Von daher sollte man doch warten, dass jeder Write request fertig ist. Und halt genau in diesem Fall würde der langsame alle anderen ausbremsen.
> Sofern man dann natürlich nicht dem langsamen Clienten weniger Pakete schickt. Also vlt nur alle 80 ms statt alle 30ms.
> Dann wäre das Problem wieder beseitigt.



Nunja, bin mir nicht sicher ob man sowas wirklich komplett synchron fahren sollte. Spontan und ohne lang zu überlegen würde ich jetzt mal sagen, dass ich, egal ob TCP oder UDP, hier nicht warten würde bis alles durch den Socket durch ist. Ab in die Write-Queue (gemanaged von Mina, Netty, <Whatever>, ...) und weiter zum nächsten. 
Aber verallgemeinern kann man das wohl nicht. Kommt sicher auch auf's Spiel/Protokoll an.


----------

