Problem mit Netzwerksynchro



  • 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.



  • Ich finde keinen Ansatz wo der Server/Client diese komische Zeit verstreichen lassen könnte bis was passiert hier mal der Ablauf:

    1. Spieler feuert (Mausklick->direkt zu Punkt 2)
    2. Client schickt "Schuss" an den Server (Datenpacket geht direkt mit ->send() raus)
    2.a Server fügt den Schuss in eine Liste ein
    3.a Client beendet Hauptschleife (recv() wird ja nur einmal abgefragt)
    3.b Server beendet Hauptschleife (wie Client)
    4. Server sammelt alle Geschosse in einem Packet (einfacher String/Speicherbereich)
    5. Server schickt Packet an Client
    5.a Server beendet Hauptschleife
    6. Client empfängt alle Schüsse und stellt diese dar

    Ich habe die Zeit von Punkt 1 bis Punkt 6 gemessen und die schwankt wie gesagt um die 500ms.
    Jetzt hab ich auf einmal Zeiten von 250ms???

    MfG
    Scarabol



  • Scarabol schrieb:

    3.a Client beendet Hauptschleife (recv() wird ja nur einmal abgefragt)

    was meinst du damit? ruft sowohl client als auch server einmal pro durchlanf recv auf? wieviele packete schickt der client maximal pro logikdurchlauf/frame ? werden alle abgefragt?



  • Genau der Client und auch der Server rufen genau einmal recv auf, pro Schleifendurchlauf.

    Der Client sollte Maximal 2 Pakete pro Frame senden (eigene Position + Schuss).

    Edit
    So ich hab jetzt auf einmal 180ms im Schnitt.
    Ich weiß nicht ganz wie ich prüfen kann wann das Packet auf dem Server ankommt, weil die Differenz ja "nur" 180ms beträgt...
    So jetzt hab ich auf einma 16ms bis der Server antwortet ich dreh durch ich habs jetzt einfach alle 15 min ma getestet und immer andere Werte???

    EDIT2
    So jetzt wirds freaky:
    Ich hab auf der Serverseite ebenfalls eine Zeitmessung eingefügt. Er misst die Zeit vom Packet "Schuss" bis er selbst die Daten rausschickt. Das ganze sieht jetzt so aus:

    // Daten an Spieler zurücksenden
    		if (players[i].connected && players[i].account->online)
    		{
    			// Geschossdaten senden
    			send(clients[i],systemlist[players[i].system].bufbullet.c_str(),(int)systemlist[players[i].system].bufbullet.size(),0);
    			if (systemlist[players[i].system].bufbullet != "&" && bullettime != 0)
    			{
    				cout << systemlist[players[i].system].bufbullet.c_str() << endl;
    				cout << (getTime()-bullettime) << endl;
    //				bullettime = 0;
    			}
    			// Gegnerdaten senden
    ...
    

    Wenn ich das bullettime = 0; einfüge dann debugt er die Zeit nur einmal, und braucht 200ms laut Client.
    Wenn ich das drinlasse spammt er die ganze Console mit den Zeiten zu, da er ja permanent Daten an den Client sendet und ich habe Schusszeiten von bis zu 12ms einfach geil da ruckelt nix mehr.

    MfG
    Scarabol



  • Scarabol schrieb:

    Genau der Client und auch der Server rufen genau einmal recv auf, pro Schleifendurchlauf.

    Der Client sollte Maximal 2 Pakete pro Frame senden (eigene Position + Schuss).

    damit flutest du doch den buffer von tcp wenn du maximal 60mal pro sekunde ein packet abrufst aber mehr als 60mal pro sekunde eines abschickst.

    wieso holst du nicht einfach alle ab? das kann die latenz durchaus erklaeren.



  • Wie kann ich den alle Pakete abrufen?

    Vielleicht so?

    while ((rc=recv(clients[i],buf,sizeof(buf)-1,0)) > 0)
    		{
    			buf[rc]='\0';
    			net_input.append(buf);
    		}
    

    Dann muss der Socket doch "non-blocking" sein, oder?
    Bleibt nur noch die Frage wie ich meinen Socket in einen non-blocking umwandle???

    EDIT
    So konnte auch den Server umstellen und alles läuft besser als vorher 😉

    Vielen Dank du warst mir ne riesen Hilfe!!! 👍 👍 👍

    MfG
    Scarabol


Anmelden zum Antworten