Bienvenue, Invité. Merci de vous connecter ou de vous inscrire.
Avez-vous perdu votre e-mail d'activation ?

Auteur Sujet: Socket qui bloque sur NotReady ! / Problème de paquets...  (Lu 19945 fois)

0 Membres et 1 Invité sur ce sujet

Crone123

  • Full Member
  • ***
  • Messages: 141
    • Voir le profil
Socket qui bloque sur NotReady ! / Problème de paquets...
« le: Août 07, 2012, 11:32:41 pm »
Bonjour,
J'avais déjà parlé de ça, j'ai un bug avec des sockets aussi bien TCP que UDP, il arrive, mais c'est purement aléatoire, c'est a dire que d'une machine a l'autre ça va marcher ou non, que les socket restent bloqués en écoute sur NotReady.

Une fois bloqué, plus moyen de transférer des données..

Donc mon code est bien standard et j'utilise les sf::Packet (mais j'avais déjà le bug sans).
Je suis passé de la 1.6 sur laquelle j'avais le bug a la 2.0 et j'ai toujours le bug.


Donc le socket reste connecté, je l'ai vu avec le TCP je peux encore envoyer des données (en UDP aussi d'ailleurs) et le serveur les reçois et les interprètes, mais le client ne peut plus en recevoir et coté serveur c'est bien indiqué "not-ready"

Il m'est déjà arrivé que le serveur soit bloqué en NotReady temporairement mais ça ne le fait quasiment jamais.

Je précise que les socket sont en "non-bloquant" et les écoutes se font en haut de la boucle principale je ne sais pas si ça peut jouer...

Dans mon cas par exemple avec les pare-feu sur off Ordi1 peut se connecter sur Ordi2 sans pb mais l'inverse ne fonctionne pas, les sockets restent bloqués. (Il va se connecter, mais au bout de quelques données échangées il va se bloquer sur "NotReady")
Et il arrive que lorsque que Ordi1 est connecté sur Ordi2 il ne reçoive plus les positions des autres joueurs parce que le socket UDP est resté bloqué sur "NotReady"....

Quelqu'un a t-il déjà eut le problème?
Quelqu'un sait-il comment le corriger?
Quelqu'un a t-il des conseils a me donner pour éviter ce genre de problèmes ou sur la meilleure utilisation possible des socket? (façon de l'utiliser)
Merci :)

EDIT: J'ai trouvé ça: http://en.sfml-dev.org/forums/index.php?topic=7435.0 qui parle du même problème mais en anglais..je suis en train de le lire pour voir...

EDIT2: En fait non, c'est un autre problème, carrément pas de connexion, enfin, ça m'est arrivé aussi, mais c'est pas mon problème actuel....et il les utilise aussi en non-bloquant et avec un timeout de 0...

EDIT3: Est-ce mieux de mettre les connexion sur Thread en mode bloquant? Ou de les laisser comme maintenant (sans thread) dans la boucle principale? En sachant que j'ai besoin de perfs et que ça ne rame pas (surtout sous Windows, je sais que Linux gère bien les Threads mais sous Windows c'est une horreur....)
« Modifié: Juin 07, 2013, 04:40:30 pm par Crone123 »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : Socket qui bloque sur NotReady !
« Réponse #1 le: Août 08, 2012, 08:21:45 am »
Il faudrait un (ou plutôt deux : client et serveur) code complet minimal qui reproduit le problème, afin que nous puissions tester.
Laurent Gomila - SFML developer

Crone123

  • Full Member
  • ***
  • Messages: 141
    • Voir le profil
Re : Socket qui bloque sur NotReady !
« Réponse #2 le: Août 08, 2012, 11:59:24 am »
Bah c'est a voir, mais c'est difficile quand on sait que dans un sens ça marche dans l'autre pas....

Ordi1 client → Ordi2 serveur ça peut marcher
Ordi2 client → Ordi1 serveur le socket va vite (0.5s) rester bloqué sur NotReady

Je vais voir si j'arrive a le reproduire en minimal...


Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : Socket qui bloque sur NotReady !
« Réponse #3 le: Août 08, 2012, 12:17:48 pm »
Il faut déjà trouver le facteur déclencheur (volume de données trop important ? envois trop rapides ? ...), et ensuite faire un petit code qui amplifie ce facteur pour être certain de opuvoir reproduire le problème à coup sûr.
Laurent Gomila - SFML developer

Crone123

  • Full Member
  • ***
  • Messages: 141
    • Voir le profil
Re : Socket qui bloque sur NotReady !
« Réponse #4 le: Août 08, 2012, 08:41:08 pm »
Et une fois le problème détecté, il faudra trouver une correction: Dans le programme en question, ou dans la SFML?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : Socket qui bloque sur NotReady !
« Réponse #5 le: Août 08, 2012, 08:43:20 pm »
Comment veux-tu répondre à cette question avant d'avoir trouvé l'origine du problème ? :P
Laurent Gomila - SFML developer

Crone123

  • Full Member
  • ***
  • Messages: 141
    • Voir le profil
Re : Socket qui bloque sur NotReady !
« Réponse #6 le: Août 08, 2012, 10:33:24 pm »
Je ne sais pas, mais la réponse sera soit l'un soit l'autre :)

Crone123

  • Full Member
  • ***
  • Messages: 141
    • Voir le profil
Re : Socket qui bloque sur NotReady !
« Réponse #7 le: Août 09, 2012, 04:05:19 am »
J'ai trouvé !
Le socket plante en envoyant un sf::Packet de 8964o.

J'ai diminué le nombre de case de map chargée a la fois (par socket, de 500 et 100), la vitesse est considérablement réduite, je passe de 7s a 40s pour une map de 500*500, la vitesse de chargement passe de 21000cases/s (450 - 500ko/s env) a 6000cases/s (116ko/s)

Je ne sais pas si on peut considérer que 8ko c'est beaucoup sur un socket, parce que plus j'envoie de données d'un coup dans un socket et plus ça se charge vite, et encore, je suis sur réseau local et je ne vais qu'as 500ko/s (avec des socket de 8ko maximum) alors que j'ai un débit maximal de 12.6mo/s, donc monter a 1 ou 2mo ne devrait normalement pas être un problème.

Maintenant, le problème n'est pas partout, donc le bug a l'air de venir des sf::Packet au transfert, mais sur certains ordis ça fonctionne, sur d'autres ça bloque.

Personnellement, j'ai déjà eut des blocages en UDP aussi, je suis obligé de limite faire lagguer le jeu en réseau en mettant les fréquences de rafraîchissement des positions des jours très basse alors que je n'envoie pas grand chose en UDP pour la position des persos, sinon le socket se bloque définitivement.

Quand je vois les autres jeux ce qu'ils peuvent envoyer je me dis que c'est pas trop normal...
Et le http par exemple, ça ne bloque pas sous prétexte que l'on télécharge a plus de 150ko/s (c'est un exemple, mais ça montre que si on arrive a atteindre des débits plus élevés sur le réseau sans bugguer ailleurs c'est que la SFML doit avoir un bug...quelque part..)

Notez que je fais bien attention a ne pas envoyer plusieurs sockets a la fois, c'est a dire que je regroupe tout ce que j'ai besoin d'envoyer a un client dans une variable et j'envoie tout a la fin de l'image, donc ça limite le nombre de socket (y compris en UDP), et pour le chargement de la map (TCP), j'attends une réponse du client indiquant qu'il a bien chargé ce que je lui ai envoyé pour lui envoyer la suite, je n'envoie pas tout d'un coup n'importe comment...

Si ça peut vous aider, voici le PC capable de faire serveur et donc d'envoyer les données, mais pour lequel ça bloque directement si il reçois un socket de 8ko (parfois beaucoup moins..).
Le PC est récent, il date de fin 2009 début 2010:
Il tourne sous Ubuntu 12.04 LTS 64bits (je n'utilises que Linux personnellement, et très rarement Windows..)
Et voici donc le résultat de la commande lspci histoire que vous aillez le détail matériel, par exemple la carte réseau ou autres si ça peut vous servir:
00:00.0 RAM memory: NVIDIA Corporation MCP78S [GeForce 8200] Memory Controller (rev a2)
00:01.0 ISA bridge: NVIDIA Corporation MCP78S [GeForce 8200] LPC Bridge (rev a2)
00:01.1 SMBus: NVIDIA Corporation MCP78S [GeForce 8200] SMBus (rev a1)
00:01.2 RAM memory: NVIDIA Corporation MCP78S [GeForce 8200] Memory Controller (rev a1)
00:01.3 Co-processor: NVIDIA Corporation MCP78S [GeForce 8200] Co-Processor (rev a2)
00:01.4 RAM memory: NVIDIA Corporation MCP78S [GeForce 8200] Memory Controller (rev a1)
00:02.0 USB controller: NVIDIA Corporation MCP78S [GeForce 8200] OHCI USB 1.1 Controller (rev a1)
00:02.1 USB controller: NVIDIA Corporation MCP78S [GeForce 8200] EHCI USB 2.0 Controller (rev a1)
00:04.0 USB controller: NVIDIA Corporation MCP78S [GeForce 8200] OHCI USB 1.1 Controller (rev a1)
00:04.1 USB controller: NVIDIA Corporation MCP78S [GeForce 8200] EHCI USB 2.0 Controller (rev a1)
00:06.0 IDE interface: NVIDIA Corporation MCP78S [GeForce 8200] IDE (rev a1)
00:07.0 Audio device: NVIDIA Corporation MCP72XE/MCP72P/MCP78U/MCP78S High Definition Audio (rev a1)
00:08.0 PCI bridge: NVIDIA Corporation MCP78S [GeForce 8200] PCI Bridge (rev a1)
00:09.0 SATA controller: NVIDIA Corporation MCP78S [GeForce 8200] AHCI Controller (rev a2)
00:0a.0 Ethernet controller: NVIDIA Corporation MCP77 Ethernet (rev a2)
00:10.0 PCI bridge: NVIDIA Corporation MCP78S [GeForce 8200] PCI Express Bridge (rev a1)
00:12.0 PCI bridge: NVIDIA Corporation MCP78S [GeForce 8200] PCI Express Bridge (rev a1)
00:13.0 PCI bridge: NVIDIA Corporation MCP78S [GeForce 8200] PCI Bridge (rev a1)
00:18.0 Host bridge: Advanced Micro Devices [AMD] Family 10h Processor HyperTransport Configuration
00:18.1 Host bridge: Advanced Micro Devices [AMD] Family 10h Processor Address Map
00:18.2 Host bridge: Advanced Micro Devices [AMD] Family 10h Processor DRAM Controller
00:18.3 Host bridge: Advanced Micro Devices [AMD] Family 10h Processor Miscellaneous Control
00:18.4 Host bridge: Advanced Micro Devices [AMD] Family 10h Processor Link Control
02:00.0 VGA compatible controller: NVIDIA Corporation GT216 [GeForce GT 220] (rev a2)
02:00.1 Audio device: NVIDIA Corporation High Definition Audio Controller (rev a1)
04:00.0 FireWire (IEEE 1394): VIA Technologies, Inc. VT6315 Series Firewire Controller

Et le PC pour lequel je n'ai pas eut de problème avec les socket de 8ko, par contre j'ai déjà eut aussi des socket bloqués donc ça arrive aussi dessus, en UDP et a d'autres moment dans le jeu (ça dépends des fois..):
Le PC est aussi récent, il date de mi 2011: (je ne rapporte pas de bugs pour des vielles machines ça n'aurait pas de sens :) )
Il tourne aussi sous Ubuntu 12.04 LTS 64bits
00:00.0 Host bridge: Intel Corporation Core Processor DRAM Controller (rev 18)
00:01.0 PCI bridge: Intel Corporation Core Processor PCI Express x16 Root Port (rev 18)
00:1a.0 USB controller: Intel Corporation 5 Series/3400 Series Chipset USB2 Enhanced Host Controller (rev 06)
00:1b.0 Audio device: Intel Corporation 5 Series/3400 Series Chipset High Definition Audio (rev 06)
00:1c.0 PCI bridge: Intel Corporation 5 Series/3400 Series Chipset PCI Express Root Port 1 (rev 06)
00:1c.2 PCI bridge: Intel Corporation 5 Series/3400 Series Chipset PCI Express Root Port 3 (rev 06)
00:1d.0 USB controller: Intel Corporation 5 Series/3400 Series Chipset USB2 Enhanced Host Controller (rev 06)
00:1e.0 PCI bridge: Intel Corporation 82801 PCI Bridge (rev a6)
00:1f.0 ISA bridge: Intel Corporation 5 Series Chipset LPC Interface Controller (rev 06)
00:1f.2 RAID bus controller: Intel Corporation 82801 SATA Controller [RAID mode] (rev 06)
00:1f.3 SMBus: Intel Corporation 5 Series/3400 Series Chipset SMBus Controller (rev 06)
01:00.0 VGA compatible controller: NVIDIA Corporation Device 0dc0 (rev a1)
01:00.1 Audio device: NVIDIA Corporation GF106 High Definition Audio Controller (rev a1)
03:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168B PCI Express Gigabit Ethernet controller (rev 06)
ff:00.0 Host bridge: Intel Corporation Core Processor QuickPath Architecture Generic Non-core Registers (rev 05)
ff:00.1 Host bridge: Intel Corporation Core Processor QuickPath Architecture System Address Decoder (rev 05)
ff:02.0 Host bridge: Intel Corporation Core Processor QPI Link 0 (rev 05)
ff:02.1 Host bridge: Intel Corporation Core Processor QPI Physical 0 (rev 05)
ff:02.2 Host bridge: Intel Corporation Core Processor Reserved (rev 05)
ff:02.3 Host bridge: Intel Corporation Core Processor Reserved (rev 05)

Voilà, a mon avis le problème viens des sf::Packet qui bien que hyper pratique, ont un problème pour transférer plus de données.
Je ne crois pas avoir déjà eut ce problème avant quand le jeu ne les utilisait pas (il utilisait les chaines standard), par contre le jeu ramait avec les chaines standard qui envoyaient des caractères vides a tout bout de champs, et j'avais d'autres problèmes du a la limite de caractères qui était fixe.

Si je me rappelle bien, quand j'utilisais encode beaucoup Game Develop (il y a environ 1an ou 1an et demi) pour créer mes jeux en 2D (c'est comme ça que j'ai connu la SFML et c'est aussi pour ça que la SFML est la première bibliothèque que j'ai appris a utiliser quand j'ai commencé a programmer en C++), j'avais crée un jeu type TPS pour tester un truc, et j'avais déjà ce bug le jeu n'arrivait plus a recevoir de données, et du au logiciel (GD) ou pas, le jeu freezait même des fois après qu'il ne puisse plus recevoir de données....bon, le freeze ne doit pas venir de la SFML puisque je n'ai pas rencontré ce problème en C++...

Voilà, la SFML 2.0 est en RC ça tombe bien, si vous trouvez ce fameux bug dans les socket ça fera une version 2.0 parfaitement stable :)
Merci :)

PS: J'utilisais Game Develop sous Windows 7 64bits, et j'ai eu le problème avec le premier PC dont j'ai parlé qui testait le jeu avec Wine (Ubuntu 10.04 LTS 64bits), 3 autres PC portables (Ordis avec lesquels j'ai testé le jeu) qui étaient sous Windows 7 64bits et une tour un peu plus ancienne (5 - 6ans) sous Windows Xp 32bits.
J'avais pris soin de faire plusieurs tests même en ne mettant que des PC's portables sous Windows 7 64bits etc pour supprimer les possibles bugs de Wine, et le jeu n'as jamais marché correctement, toujours un moment ou un joueur ne recevait plus rien, si c'était pas plusieurs joueurs....

PS2: J'ai aussi en C++ testé 2 versions de mon serveur, une version graphique, qui affiche tout ce qui se passe sur le serveur en graphique, et une version console (terminal) qui fonctionne de la même façon sans faire les calculs graphiques (en supposant que ça aurait pu ralentir le trafic a cause des calculs), et j'obtiens le même résultat, hors mis que la version terminal consomme évidement beaucoup moins de ressources sur l'ordi.

PS3: J'ai déjà bossé un maximum  sur l'optimisation du jeu, et a chaque fois ça se bloquait sur les socket, quel que soit l'optimisation, aujourd'hui le jeu a un algorithme pour charger dynamiquement les maps sur les clients (en temps réel) et rapidement, et en consommant le moins de connexion possible, disons que maintenant plus on consomme et plus ça charge vite, mais j'ai toujours eu ce bug en utilisant les sockets SFML (TCP/UDP)

L'envoi ne doit pas poser de problèmes, c'est la réception qui pose problème a mon avis puisque c'est celui qui reçoit qui bloque et pas celui qui envoie, et que j'ai testé de connecter plusieurs clients a la fois en même temps, je n'ai pas de perte de vitesse, donc le jeu est capable d'envoyer tout ça sans problèmes sur les 2 clients ça va aussi vite que si ils étaient tout seuls (sinon ça bloquerait coté serveur), et le débit est stable. En revanche la réception doit avoir un bug qui paralyse le socket en cours de réception de données...

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : Socket qui bloque sur NotReady !
« Réponse #8 le: Août 09, 2012, 08:15:58 am »
Bien :)

Maintenant il ne te reste plus qu'à écrire un client/serveur minimal qui ne fait qu'envoyer des paquets de 8964 octets (je pense que la "vraie" limite est en fait pas loin de 8192). Comme ça je pourrai d'une part vérifier qu'il n'y a aucune erreur dedans, et d'autre part, avec un peu de chance, reproduire le problème chez moi et debugger.
Laurent Gomila - SFML developer

Crone123

  • Full Member
  • ***
  • Messages: 141
    • Voir le profil
Re : Socket qui bloque sur NotReady !
« Réponse #9 le: Août 10, 2012, 02:35:56 am »
J'ai fait le code minimal qui bug, j'ai fait quelques tests, donc j'ai déjà des résultats de tests a vous fournir en même temps que le code, c'est d'ailleurs assez intéressant :)
Voici le lien du 7z contenant les sources, une version compilée pour Ubuntu 64 bits avec les .so de la SFML2, 2 fichiers de démarrage (Client et Serveur) pour l’exécutable, et le fichier Readme.txt contenant mon test.
http://dl.smglive.org/Crone123/SF-SOCKET-TEST.7z
env 368ko en 7z, 1.1Mo une fois extrait.

Le fichier StartClient.sh est a adapter, vous devez mettre l'IP de l'Ordi sur lequel vous avez lancé le serveur a la place de celle qui est présente.
Le fichier StartServer.sh n'as pas besoin d'être adapté :)

Note: C'est mieux de lancer le serveur avant de lancer le client, puisque le client va essayer de se connecter dans le vide sinon...

Les sources: (présentes dans l'archive)
main.cpp
#include <SFML/Network.hpp>
#include <string>
#include <sstream>
#include <iostream>
#include <ctime>
using namespace std;

int main(int argc, char * argv[])
{
    bool Continue(true);//Mettre a false = fermer le programme.
    string Mode; //Variable contenant le mode (client ou serveur)
    sf::IpAddress IP;//Variable contenant l'IP, uniquement pour se connecter au serveur.
    int Port(36000); //Variable contenant le port utilisé.

    /** Recuperation des paramètres de commande **/
    if(argc >= 2)
    {
        Mode = argv[1];
    }
    if(argc >= 3)
    {
        IP = string(argv[2]);
    }
    else if(Mode != "--server")
    {
        cout << "Veulliez entrer une IP pour choisir le serveur." << endl;
        return 0;
    }

    /** Test **/
    if(Mode == "--client")
    {
        /** PARTIE CLIENT **/
        sf::TcpSocket Serveur;//Socket pour se connecter au serveur.
        Serveur.setBlocking(false);
        bool connected(false);
        while(Continue)
        {
            if(!connected)
            {
                sf::Socket::Status Rep = Serveur.connect(IP, Port);
                if(Rep == sf::Socket::Done)
                {
                    cout << "Connexion reussie a " << IP.toString() << endl;
                    connected = true;
                    sf::Packet Paquet;
                    Paquet << "<Send>";
                    Serveur.send(Paquet);//On demande un envoi de socket au serveur.
                }
                else if(Rep == sf::Socket::NotReady)
                {
                    cout << "Connexion impossible: NotReady" << endl;
                }
                else if(Rep == sf::Socket::Error)
                {
                    cout << "Connexion impossible: Erreur" << endl;
                }
                else
                {
                    cout << "Connexion impossible: Autre" << endl;
                }
            }
            else //Connnecté !
            {
                sf::Packet Paquet;
                sf::Socket::Status Rep = Serveur.receive(Paquet);
                static int compteur(0);
                if(Rep == sf::Socket::Done)
                {
                    ++compteur;
                    string Tmp;
                    Paquet >> Tmp;
                    cout << time(0) << ": Socket N " << compteur << ": " << Tmp.size() << "o" << endl;
                    Paquet.clear();
                    Paquet << "<Send>";
                    Serveur.send(Paquet);//On demande un envoi de socket au serveur.
                }
                else if(Rep == sf::Socket::Error)
                {
                    cout << time(0) << ": Erreur de reception du socket !" << endl;
                }
                else if(Rep == sf::Socket::Disconnected)
                {
                    cout << time(0) << ": Connexion terminee !" << endl;
                    Continue = false;
                }
            }
            sf::sleep(sf::seconds( 1 / 60)); //Simulation d'un jeu tournant a 60FPS.
        }
    }
    else if(Mode == "--server")
    {
        /** PARTIE SERVEUR **/
        sf::TcpListener Listener;
        if(Listener.listen(Port) == sf::Socket::Done)
        {
            cout << "Ecoute du port: " << Port << endl;
        }
        else
        {
            cout << "Impossible d'ecouter le port: " << Port << endl;
            return 0;
        }
        sf::TcpSocket Client;
        Client.setBlocking(false);
        Listener.setBlocking(false);
        bool connected(false);
        while(Continue)
        {
            static int compteur(0), taille(100);
            if(!connected)
            {
                sf::Socket::Status Rep = Listener.accept(Client);
                if(Rep == sf::Socket::Done)//Client connecté, on prépare l'envoi.
                {
                    cout << time(0) << ": Connexion de: " << Client.getRemoteAddress() << endl;
                    cout << time(0) << ": Envoi de donnees... " << endl;
                    connected = true;
                    taille = 100;
                    compteur = 0;
                }
            }
            else
            {
                sf::Packet Paquet;
                sf::Socket::Status Rep = Client.receive(Paquet);
                if(Rep == sf::Socket::Done)
                {
                    string CT;//Contenu du paquet
                    Paquet >> CT;
                    if(CT == "<Send>")
                    {
                        Paquet.clear();
                        ++compteur;
                        CT.clear();
                        for(unsigned int compteur2(0); compteur2 < taille; ++compteur2)
                        {
                            CT += '1';
                        }
                        Paquet << CT;
                        bool CW(true);//Continue While
                        int N(0);
                        while(CW)
                        {
                            Rep = Client.send(Paquet);
                            if(Rep == sf::Socket::Done)
                            {
                                CW = false;//On quitte la boucle
                                cout << time(0) << ": Envoye: N " << compteur << ": " << taille << "o" << endl;
                                taille += 100;
                            }
                            else if(Rep == sf::Socket::NotReady)
                            {
                                cout << time(0) << ": NotReady: N " << compteur << ": " << taille << "o" << endl;
                            }
                            else if(Rep == sf::Socket::Error)
                            {
                                cout << time(0) << ": Erreur: N" << compteur << ": " << taille << "o" << endl;
                            }
                            if(N == 20)
                            {
                                cout << "Stoppe pour 20 erreur d'affilee !" << endl;
                                CW = false;
                            }
                            ++N;
                        }
                    }
                }
                else if(Rep == sf::Socket::Error)
                {
                    cout << time(0) << ": Erreur de reception du socket !" << endl;
                }
                else if(Rep == sf::Socket::Disconnected)
                {
                    Client.disconnect();
                    connected = false;
                    cout << "Client deconnecte !" << endl;
                }

            }
            sf::sleep(sf::seconds( 1 / 60)); //Simulation d'un jeu tournant a 60FPS.
        }
    }
    else
    {
        cout << "Les options possibles sont --client IP et --server !" << endl;
    }
    return 0;
}

 

Démarrer:
./SF_SOCKET_TEST [mode] [IP]
Mode peut être:
--server (dans ce cas, pas besoin de spécifier IP)
--client (dans ce cas, IP = Serveur auquel se connecter)
Le port est par défaut 36000 est modifiable dans les sources :)

J'ai crée ça avec QtCreator, donc les fichiers .pro etc sont dans l'archive :)

C'est pas du grand code on est d'accord, mais c'est le code minimal qui reproduit le bug :)
Vous pouvez bien entendu l'adapter comme bon vous semble pour vos tests :)

Et le Readme.txt (Pour le cas ou vous n'utilisez pas l'archive...)
Socket sur lequel ça bloque en fonction des conditions:
La taille est progressive, elle commence a 100o et augmente de 100o a chaque nouveau socket.
1 = 100
2 = 200
3 = 300
...
Le sens d'envoi des données va de Serveur vers Client, c'est donc le client qui reçois, et c'est lui qui va bloquer un moment.
Localhost: (AMD Athlon II X2 a 2.7Ghz) (généralement pas de pb en Localhost)
Socket N 5898: 589800o
Durée du test: Environ 10 - 15s

→ A bloqué 1 fois, les plantages sont rares comme je l'ai dit en localhost j'en ai pas vu sur l'I5, et j'en ai eu 1 sur l'AMD Athlon (voir ci dessus) et en laissant tourner quelques minutes j'en ai pas eu d'autres.

A ce test je vois d'ailleurs que l'I5 trace l'AMD Athlon niveau vitesse c'est peut être pour ça qu'il supporte mieux sur le test en Ethernet.

Ils ont dépassé les 30000sockets sans bugguer ensuite en local, rien d'étonnant, en local mon jeu a eu de très rares bugs.







Réseau Local Ethernet a 100Mb: (12.6Mo/s, vitesse réelle [testé])

Ethernet: Ordi1 Serveur (AMD Athlon II X2 a 2.7Ghz), Ordi2 Client (Intel Core I5 Dual-Core avec 2 thread par coeur [4coeurs virtuels] a 3.2Ghz):
Socket N 406: 40600o
Socket N 419: 41900o
Socket N 406: 40600o
Durée du test: 1.5 - 2s environ.

Ethernet: Ordi2 Serveur (Intel Core I5 Dual-Core avec 2 thread par coeur [4coeurs virtuels] a 3.2Ghz), Ordi1 Client (AMD Athlon II X2 a 2.7Ghz):
Socket N 73: 7300o
Socket N 73: 7300o
Socket N 72: 7200o
Durée du test: 1 - 1.5s environ.

Dans les 2 cas, c'est le client qui bloque niveau reception, normal c'est lui qui reçois le plus.
Si vous faites le test dans l'autre sens, c'est a dire serveur qui reçois c'est le serveur qui va bloquer a la reception.

Comme vous le verrez sûrement les tests "local" (127.0.0.1) ne bloquent quasiment jamais....et vous voyez que en fonction de la condition, les tests sont a peu près identiques.

Et sur un PC plus puissant (Le PC avec l'I5 a tout de plus puissant que le PC avec l'AMD Athlon) ça tiens mieux, mais ça se compte a 1s d'écart sur le test, puisque l'un supporte 8ko, l'autre 40ko.
Mais les 2 PC sont déjà des PC's bien puissants, des Jeux Open GL (Nexuiz, Xonotic, Red Eclipse, etc...) passent entre la qualité Maximum et une qualité haute pas loin en fonction du jeu (Pour le PC avec i5 tout est toujours au max), et pour des Jeux Direct X, bien que je n'y joue pas beaucoup puisque je suis majoritairement sous Linux, pour l'I5 tout tourne en qualité maximum avec par contre Anticrenelage et Antialiasing au maximum a X2 (ça ne supporte pas trop plus).
L'AMD Athlon supporte moins, mais il supporte quand même les jeux en qualité standard pour les jeux comme Crysis Warhead, et sinon les jeux comme Oblivion, Skyrim,  etc... passent en qualité Haute sans problèmes.
Tout ça bien sur sans anti-crenelage et anti-aliasing ou sans dépasser le X2 ou billinéaire comme pour l'I5 sans quoi ça peu ralentir un peu...

Donc les 2 PC sont bien puissants, aucun problèmes là dessus je me répète mais ça ne peut pas venir du fait que les machines soient trop peu puissantes ou trop anciennes :) (elles sont récentes)

Donc j'espère que vous arriverez a reproduire le bug avec ça et que vous arriverez a voir d'où il viens et le corriger, si y a des tests a faire, je veux bien tester chez moi les modifications si vous avez besoin (histoire de comparer les tests, et voir si c'est résolu), en sachant que a partir de mardi soir je ne suis pas là pendant 1 semaine (vacances) mais d'ici là, je n'ai aucun problèmes a tester, et après non plus.
En vacances je n'aurais que mon PC portable donc seul et sans d'autres ordis a moi c'est pas génial pour faire ce genre de tests....
Ah, un dernier détail: Le test est ici en TCP, le bug se produit aussi en UDP, sauf qu'en UDP c'est pas possible de savoir si l'autre a reçu ou pas le paquet, donc pour un test de ce genre c'est pas génial....

Voilà, Merci d'avance :)

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : Socket qui bloque sur NotReady !
« Réponse #10 le: Août 10, 2012, 08:14:09 am »
Quand un PC bloque, il y a quoi affiché sur la sortie standard juste avant le bloquage ?

Et au fait :
sf::sleep(sf::seconds( 1 / 60)); //Simulation d'un jeu tournant a 60FPS.
1 / 60 == 0 car c'est une division entière. Essaye plutôt 1.f / 60.
Laurent Gomila - SFML developer

Crone123

  • Full Member
  • ***
  • Messages: 141
    • Voir le profil
Re : Socket qui bloque sur NotReady !
« Réponse #11 le: Août 10, 2012, 04:02:35 pm »
Ah oui effectivement j'ai oublié le détail que c'était du int....Merci :)

Quand un PC bloque, bah, il n'affiche rien de plus que ce qu'on affiche avec le programme (cout <<), coté client il ne va plus rien afficher (il affiche le message du dernier socket reçu et rien de plus après), coté serveur on a le droit a 20 erreur disant que le client est NotReady avant que je coupe ma boucle.
Si vous ne coupez pas la boucle le serveur vous renverra indéfiniment cette erreur parce que le client ne reçois plus rien (bloqué)...

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : Socket qui bloque sur NotReady !
« Réponse #12 le: Août 10, 2012, 05:44:14 pm »
Ok, bon je vais essayer de tester ça mais j'ai peu de temps libre alors je ne te promets rien.
Laurent Gomila - SFML developer

Crone123

  • Full Member
  • ***
  • Messages: 141
    • Voir le profil
Re : Socket qui bloque sur NotReady !
« Réponse #13 le: Août 10, 2012, 05:44:58 pm »
OK Merci :)

Crone123

  • Full Member
  • ***
  • Messages: 141
    • Voir le profil
Re : Socket qui bloque sur NotReady !
« Réponse #14 le: Octobre 22, 2012, 10:55:27 pm »
J'ai du nouveau concernant ce bug, ou un bug similaire.
Donc, je ne cherche pas a dire que la SFML est bugguée hein, j'aime beaucoup cette bibliothèque, mais j'étais en train de transférer des données d'un serveur vers un client (une map pour un jeu).
Et encore une fois le socket a bloqué, en TCP avec la SFML 2.0RC.
J'ai du trasnférer quelque chose comme 7 ou 8 mo a une vitesse de 160ko/s sur un réseau local fillaire et de ma machine a elle même (donc c'est pas un problème de vitesse du réseau).
Donc, classique, tout se passait très bien, et d'un coup la transmission s'est arrêtée.
Coté client c'est du NotReady si je veux envoyer.
Coté serveur, lancé en débug sur GDB, j'ai eut ce message:
Program received signal SIGPIPE, Broken pipe.
0x00007ffff5d1f2cc in __libc_send (fd=<optimized out>, buf=<optimized out>,
    n=<optimized out>, flags=<optimized out>)
    at ../sysdeps/unix/sysv/linux/x86_64/send.c:33
33      ../sysdeps/unix/sysv/linux/x86_64/send.c: Aucun fichier ou dossier de ce type.
(gdb)
Un plantage de ce type, ça ne peut pas venir de mon programme directement puisque je ne manipule pas directement ces fichiers, j'utilise la SFML pour le faire et voilà la preuve du bug écrit dans le backtrace:
(gdb) bt
#0  0x00007ffff5d1f2cc in __libc_send (fd=<optimized out>,
    buf=<optimized out>, n=<optimized out>, flags=<optimized out>)
    at ../sysdeps/unix/sysv/linux/x86_64/send.c:33
#1  0x00007ffff731441b in sf::TcpSocket::send(void const*, unsigned long) ()
   from ./libsfml-network.so.2
#2  0x00007ffff7314628 in sf::TcpSocket::send(sf::Packet&) ()
   from ./libsfml-network.so.2
#3  0x00000000004608b9 in Server_Main::server_Send (this=0x8f0500,
    Command=..., Client=0xa995e0) at Server_Main_SR.cpp:47
#4  0x0000000000432230 in Server_Main::OnUpdate (this=0x8f0500)
    at Server_Main.cpp:646
#5  0x000000000042d5fe in Server_Main::Server_Main (this=0x8f0500, parent=0x0,
    Position=..., Size=..., LTmp=0x778570, G=false) at Server_Main.cpp:190
#6  0x000000000040e85a in main (argc=2, argv=0x7fffffffe258) at main.cpp:176
(gdb)
Bon, je ne voudrais pas voir des bugs partout (ou donner l'impression que je suis parano..), mais cette fois ci je pense que ça peut être pris au sérieux étant donné que l'effet coté client est un NotReady continu (comme précédemment dit), le transfert s'arrête comme je l'avais dit.
Et coté serveur cette fois ci j'ai eut droit a un crash, d'habitude je relançais directement le serveur j'attendais pas quelques secondes avec le débugger pour voir d'où ça pouvait venir. (donc j'ai jamais vu si ça crashait ou pas..)
Donc normalement maintenant vous pouvez savoir d'où viens précisément le bug :)
Merci :)