Komisches Verhalten von select() mit Timeout unter Windows



  • Huhu,

    aktuell bin ich dabei, ein Programm zur Verwaltung eines Gameservers zu schreiben. Bisher haben ich dazu eine Programm von einer anderen Person verwendet, dass in C# geschrieben ist. Dieses Programm hat so einige Probleme, wie z.B., dass es nach einigen Stunden teils Overflow Exceptions auswirft. Da ich das Programm außerdem am liebsten auch 24/7 auf meinem Linux Server laufen lassen möchte, habe ich mich dazu entschlossen, ein eigenes Programm komplett neu in C++ zu schreiben. Mein Code um eine Verbindung mit dem Server herzustellen sieht wie folgt aus:

    while (!connected) {
         if (connectCounter == 0)
            std::cout << "Trying to connect..." << std::flush;
        else
            std::cout << "." << std::flush; // add point
    
        connectCounter++;
    
        int selectSize = 0;
        struct timeval timeout;
        timeout.tv_sec = 5;
        timeout.tv_usec = 0;
        fd_set fds;
        FD_ZERO(&fds);
        FD_SET(mysocket, &fds);
    
        selectSize = select(mysocket + 1, &fds, 0, 0, &timeout);
        if (selectSize == 1) {
            // we might now be logged in, check routines
            connected = true;
         }
    }
    

    Probleme habe ich jetzt (unter Windows), wenn der Server offline ist und die "Connection" Schleife durchläuft. Normalerweise sollte es so sein, dass das Programm versucht, eine Verbindung herzustellen. Klappt dies nicht, wird der Vorgang nach 5 Sekunden (Timeout) wiederholt und es wird ein neuer Versuch gestartet. Das Result in der Ausgabe sollte dann sein, dass dort steht "Trying to connect..." und dann alle 5 Sekunden (falls gescheitert), ein neuer Punkt hinzugefügt wird. Nun ist es aber so, dass teils komplett zufällig das Programm "Trying to connect..." ausgeben wird und dann plötzlich einen Punkt nach dem anderen rausfeuert, ohne die 5 Sekunden abzuwarten. Dies passiert aber nur hin und wieder nicht bei jedem Start des Programmes.

    Exakt dass selbe Probleme habe ich mittlerweile auch bei der C# Applikation des Kollegen. Ich habe mir den Code zwar noch nicht genau angeschaut, aber dieser wird sicherlich auch ähnlich mit Timeouts etc. arbeiten. Der Knüller ist aber, dass ich dieses Problem in der C# App des Kollegen erst habe, seit ich vor 2 Wochen meinen PC formatiert und neu aufgesetzt habe. Die C++ App habe ich leider erst nachher geschrieben, aber ich vermute sie hätte vor dem Formatieren genau wie C# App auch, hinsichtlich der Einhaltung der 5 Sekunden Timeouts, funktioniert. Unter Linux funktioniert das ganze übrigens reibungslos und ohne derartige Fehler.

    Jetzt habe ich mal ein bisschen rumgespielt und noch eine Zeile Code hinzugefügt bzw. bearbeitet, nämlich:

    selectSize = select(mysocket + 1, &fds, 0, 0, &timeout);
    std::cout << selectSize << std::endl;
    

    Und tatsächlich schaut die Ausgaben unter Windows jetzt mal so:

    Trying to connect...0.0.0.0.0.0.0.0.0.0.1.0
    

    dann mal so

    Trying to connect...1.0.0.0.1.0.1.0.0.0.1.0
    

    Der Gameserver ist ja offline, also sollte bis zum Hochfahren das Ergebnis von "selectSize" immer 0 sein. Unter Linux ist das auch so, da gibt es keinerlei solche falschen Abweichungen.

    Wie gesagt habe ich leider den Code der C# Applikation des anderen Coders noch nicht angeschaut, aber der wird ähnliche Funktionen verwenden und auch seine Applikation hat dieses Fehler hin und wieder und das absolut zufällig und das alles beobachte ich zum ersten Mal, seit ich Windows formatiert habe, vorher hatte in mit der C# Applikation nie ein solches Problem und ich denke fast, dass es auch mit meiner eigenen C++ Applikation nicht aufgetreten wäre.

    Bin gerade absolut verzweifelt, zwar läuft das Programm auf Linux einwandfrei und kann 24/7 betrieben werden, aber ich will es unbedingt unter Windows zum Laufen bekommen und erkenne einfache keine Konsistenz bzw. Reproduzierbarkeit, die diesen Fehler seit dem Formatieren hervorruft.

    Ich bin für jede Hilfe oder jeden Rat dankbar.




Log in to reply