Problem mit Netzwerksynchro



  • Hi,

    ich hab ein kleines Netzwerkspiel geproggt, jeder Spieler hat ein Raumschiff und ballert andere ab (!Wehe ich höre Kommentare zum Spielprinzip! :D)

    Bisher wartet der Server auf eine Antwort vom Client und verarbeitet alles und schickt das Ergebnis wieder zurück. Der Client benimmt sich genauso. So wie sich jeder jetzt wohl denkt und woran ich anfangs nicht gedacht hab: Wenn der Client bzw. der Server unterschiedlich schnell laufen, passierts ja das die Buffer irgendwann voll sind oder das Packete (wie bei der Post) zu spät ankommen.

    Wie kann ich das Problem lösen ich hatte bisher an Threads gedacht, aber bisher immer nur gehört das die schnell zu Problemen führen. Gibt es vielleicht noch andere Lösungen?

    Konkret hab ich jetzt das Problem das der Spieler zwar schießt aber der Schuss erst 3 sek später angezeigt wird...
    Daher würd ich später gern Interpolation einbaue und würde das gern jetzt schon in meiner Lösung berücksichtigen.

    MfG
    Scarabol



  • Du must Server und Client schon gleich schnell laufen lassen... 🙄
    Ist bei kommerziellen Spielen ja auch so 😉

    Zum Beispiel mit VSync. 😃



  • Ich dachte vielleicht auch das es möglich ist den Server schneller laufen zu lassen als den Client, sodass der Client ein ok oder fertig sendet wenn er bereit ist und der Server schickt ihm dann die Daten...

    MfG
    Scarabol



  • du sagst dass die buffer volllaufen, obwohl die gegenstellen abwechselnd daten schicken und willst es mit threads loesen?

    andersrum, die netzwerkbuffer laufen voll obwohl maximal ein packet drin sein kann und du willst das netzwerkproblem loesen indem du threads implementierst?

    also irgendwie solltest du genauer spezifizieren welcher teil ein problem darstellt. netzwerk oder logik? und falls du es nicht genau analysieren kannst, schreib auf was passiert und vielleicht koennen wir die tipps zum debuggen geben 😉



  • So also Server und Client laufen nun gleich schnell, der Server wartet bis der Client etwas sendet und umgekehrt.

    Wenn der Spieler schießt schickt er die Info an den Server und dieser bewegt dann das Geschoss durch den Raum.

    Das Problem ist jetzt das das Geschoss noch einige Zeit spürbar an der Stelle aushart an der es abgefeuert wurde bis es sich bewegt. Die macht den Eindruck, als ob der Server bzw. Client überlastet sei. Beide laufen aber mit 60fps und die übrige Grafik ect. ruckelt keinsewegs...

    Wie kann ich das Problem lösen?

    [Edit]
    Zwischen Schuss und Daten liegen etwa 550ms. Es sollten aber bei 60fps doch nur etwa 17 sein. Wie kann das sein?

    MfG
    Scarabol



  • const int ON = 1;
    setsockopt(Socket,SOL_TCP, TCP_NODELAY,&ON,sizeof(ON));
    

    😉



  • Ist das sinnvoll? Bzw. führt das dann nicht wieder zu anderen Problemen, muss ich weiter etwas beachten? Kann den Code im Moment nicht testen, aber auf den ersten Blick wird er wohl Wunder wirken 🙂
    Auch wenns dann meine Bandbreite auffrisst...

    Ich habe für die Netzwerkcommunication eine eigene Klasse erstellt. Würde es Sinn machen die Daten, die an den Server gesendet werden sollen, während eines Frames zu sammeln und erst am Ende der Schleife also kurz bevor die Scene gerendert wird oder kurz danach als gesammeltes Packet an den Server zu schicken?

    MfG
    Scarabol



  • Scarabol schrieb:

    Ist das sinnvoll? Bzw. führt das dann nicht wieder zu anderen Problemen, muss ich weiter etwas beachten? Kann den Code im Moment nicht testen, aber auf den ersten Blick wird er wohl Wunder wirken 🙂
    Auch wenns dann meine Bandbreite auffrisst...

    Ich habe für die Netzwerkcommunication eine eigene Klasse erstellt. Würde es Sinn machen die Daten, die an den Server gesendet werden sollen, während eines Frames zu sammeln und erst am Ende der Schleife also kurz bevor die Scene gerendert wird oder kurz danach als gesammeltes Packet an den Server zu schicken?

    ich hatte erwartet, wenn du so verzweifelst ueber die latenz bist, dass du eh alles was in einem packet sein soll am stueck abschickst.

    wenn du das so machst, wirst durch dieses flag keine nachteile haben, wobei ich natuerlich nicht garantieren kann, dass das der einzige grund fuer die verzoegerung ist, war blanke annahme dass du tcp benutzt und uebers internet testen kannst 😉



  • rapso schrieb:

    ... uebers internet testen kannst 😉

    Wieso über Internet testen ich benutzt das locale Netz (127.0.0.1)?

    MfG
    Scarabol



  • Scarabol schrieb:

    rapso schrieb:

    ... uebers internet testen kannst 😉

    Wieso über Internet ...

    meine sarkastische art zu sagen dass du wenig verraten hast und ich nur aufgrund blanker vermutungen versuche zu helfen :p



  • Hi,

    ich hab die sockets mit setsockopt geändert aber das Problem bleibt das gleiche.

    MfG
    Scarabol



  • erzaehl mehr ueber die architektur vom client/server und das testsystem. ist es ein single/dual/quadcore? hat der client threads? hast du irgendwelche prioritaeten vergeben? wie sorgst du dafuer dass der server trotz mehrere sockets nicht stallt?
    versuch vielleicht nen minimalsystem zu basteln, ohne rendering usw. einfach nur kommunikation und ob es dann gut laeuft.



  • uff, öhm ja ich poste dazu noch was, wenn ich Zeit hab...

    Danke für die Hilfe, immerhin seh ich jetzt wieder einen Ansatz.

    MfG
    Scarabol



  • ALLLSOOO

    Ich hab anfangs ein Beispiel aus dem Inet benutzt zum Thema Sockets. Das Beispiel hab ich dann einfach erweitert und es funktionierte soweit alles. Nun stößt der Code leider an seine Grenzen genau an dem Punkt wo mein Spiel eigentlich spielbar sein sollte, weil ich die wichtigsten Sachen hinzugefügt habe.

    Ich habs auch schon mit verschiedenen Netzwerk Libs versucht, aber nach allem hin und herkonvertieren und ersetzten und ummodeln bin ich zu dem Entschluss gekommen, dass ich gern weiter mit den Sockets und meiner eigenen Netzwerkklasse arbeiten möchte.

    Ein Problem ist das ich trotz TCP einige Pakete auf der Client Seite nicht erhalte. Wenn ich Breakpoints setze um das Verhalten zu untersuchen, funktioniert es und die Pakete kommen an. Ich bin im Moment ein bischen confused über das ganze und muss mich erstma wieder eindenken bzw. ne Strategie überlegen, wie ich das ganze angehe und verbessere, aber vor allem was ich überhaupt verbessern sollte und kann.

    Falls einer Ideen hat die mir das Leben erleichtern immer nur her damit...

    MfG
    Scarabol



  • Also die Pakete gehen nicht mehr verloren, aber die Zeit zwischen Schuss und Daten für Schuss verhält sich immernoch komisch.

    Zuerst ist sie niedrig auf 80 ms und steigert sich dann in 50er Schritten auf 500-600ms da hält sie sich dann mal plus mal minus 100. Wie kommt das nur?

    Die kurze Zeit am Anfang könnte daran liegen, dass die Engine nicht voll rendert, oder dass ein Buffer oder sowas vollgeschrieben wird aber dann bleibts doch nicht einfach bei 600 hängen???

    Ich versteh das irgendwie nicht...

    MfG
    Scarabol



  • Scarabol schrieb:

    Falls einer Ideen hat die mir das Leben erleichtern immer nur her damit...

    normalerwise, wenn sich etwas beim debuggen und release anders verhaelt, versucht man den input und output vom release aufzuzeichnen und im debug durchzugehen. du koenntest also ein tool dazwischen stecken was nichts anderes macht als die daten weiter zu reichen und sie auf festplatte abzulegen und fuer debuggen koenntest du mit dem tool einfach wieder die daten abschicken an den server.

    Zuerst ist sie niedrig auf 80 ms und steigert sich dann in 50er Schritten auf 500-600ms da hält sie sich dann mal plus mal minus 100. Wie kommt das nur?

    Die kurze Zeit am Anfang könnte daran liegen, dass die Engine nicht voll rendert, oder dass ein Buffer oder sowas vollgeschrieben wird aber dann bleibts doch nicht einfach bei 600 hängen???

    vielleicht laeuft der client schneller als der server und ab irgend ner stelle wird ein interner buffer von tcp voll und dann kann der client garnicht mehr schneller sein.

    testest du mit zwei clients? vielleicht holt sich der server nicht alle packete ab die ankommen, sondern immer nur eines und bei zwei clients laeuft das vielleicht deswegen immer langsammer. oder der eine client sendet ab und zu noch zusatzdaten (z.b. den schuss) und der server nimmt aber nur ein packet entgegen oder...

    Ein Problem ist das ich trotz TCP einige Pakete auf der Client Seite nicht erhalte.

    also du darfst dich in diesem fall auf tcp verlassen, eher wird alles langsam als das ein packet verloren geht. auch verfaelschungen des packets sollten eher nicht passieren.

    Zuerst ist sie niedrig auf 80 ms

    bei localhost hab ich sonst <1ms latenz. falls der server mit 60hz laeuft, wie du schon sagtest, duerfte es nicht bei ueber 16.67ms liegen.



  • Gibt es eine einfach Methode die Latenz zu messen?

    MfG
    Scarabol



  • von was? von deinem netzwerk?
    ping
    z.b. ping localhost
    kannst auch id externe ip verwenden die du mit ipconfig abfragen kannst. beides sollte <1ms sein.



  • Danke für die Hilfe,

    ich würde die Latenz im Programm selber anzeigen und erfassen, wie mach ich das?

    Zähl ich die Zeit zwischen den Paketen des Servers?
    Falls ja kommt die Latenz ja nicht unter 1000/60ms = 17ms weil ja das Spiel mit 60fps läuft. Ich sollte vielleicht den Netzwerkkram in einen Thread auslagern oder?

    MfG
    Scarabol



  • naja, die latenz bei spielen ist meistens die zeit vom abschicken einer nachricht bis zum empfang der reaktion. du kannst also in das packet die client zeit abspeichern und der server muss dann die zeit durchschleifen und bei der antwort mitschicken. natuerlich kann der server noch die empfangszeit und die zuruecksendezeit mit abspeichern im packet (zum debuggen).

    threads sollten die latenz nicht verkleinern (normalerweise steigern threads sogar die latenz wenn jeder thread einen anderen task macht). denn das abarbeiten des nachricht wird ja eh im naechsten durchlauf der bei 60hz ist durchgefuehrt.

    ich denke darum musst du dir auch nicht wirklich gedanken machen, dein problem liegt bei gefuehlten 500ms, die 16ms sollten da nicht kritisch sein.


Anmelden zum Antworten