IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

[Réseau] Performance des sockets c++


Sujet :

C++

  1. #1
    Membre confirmé

    Profil pro
    Inscrit en
    Mars 2002
    Messages
    115
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 115
    Par défaut [Réseau] Performance des sockets c++
    Bonjour à tous
    Je travaille actuellement à l'élaboration d'un jeu 3D en C++.
    Simplifions en disant qu'il s'agit d'une sorte de bataille navale à N joueurs
    J'ai un vrai souci vis à vis des sockets winsock qui permettent de gérer les aspects réseaux (TCP, recv non bloquants)

    a) En effet, le process principal (le main) est géré par GlutMainLoop()
    b) Parallèlement en mode Server, un Thread de priorité THREAD_PRIORITY_BELOW_NORMAL permet de gérer l'attente des connexions TCP

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    while(1)
    {
      if(accept(premier_slot_disponible))
         ...
    }
    c) Dès que la première connexion est enregistrée, un thread de priorité THREAD_PRIORITY_BELOW_NORMAL permet côté Serveur de faire des receive non bloquants sur tous les slots réseau libres
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    while(1)
    {
       for(int i = 0 ; i < nbConnectes ; i++)
       {
          recv(slot[i],buffer);
          if(strlen(buffer) != 0)
                    Redispatch(i,buffer) // renvoie l'info à tous les clients
       }
    }
    d) Côté client, deux threads priorité THREAD_PRIORITY_BELOW_NORMAL gèrent
    - l'envoi des messages

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    while(1)
    {
      switch(dataToSend)
      {
      case CHAT:
         send(server,...)
         break;
      case UNITY_MOVED:
         send(server,...)
      break;
      default:;
    }
    -la réception des messages
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    while(1)    
    {
        recv(socket, buffer)
        if(strlen(buffer)) 
           Traitement(buffer);
    }
    L'ensemble marche bien mais les traitements réseaux sont très lents. Lorsque je teste 1 ou 2 instances de l'exe sur la même machine, en réseau local (127.0.0.1), plusieurs secondes peuvent passer entre l'envoi de la donnée depuis un client (un texte de chat par exemple) et son affichage sur les autres clients
    Si j'augmente la priorité des threads, c'est l'OpenGL qui devient subitement plus lent et le nombre de fps diminue.
    Que faire, que changer dans le moteur réseau ?
    Merci d'avance

  2. #2
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    recv(slot[i],buffer);
    if(strlen(buffer) != 0)
    recv prend 4 arguments.
    Appliquer strlen ici est non seulement inutile, mais devrait aussi provoquer des erreurs de segmentation de temps en temps.

  3. #3
    Membre confirmé

    Profil pro
    Inscrit en
    Mars 2002
    Messages
    115
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 115
    Par défaut
    Je sais bien que recv prend 4 arguments... Sinon je n'aurais pas précisé que le programme marche :-) C'est juste pour simplifier la lisibilité du code posté que j'ai volontairement squizzé les éléments non essentiels
    En revanche pour le strlen() > 1 (et non zéro), que proposes-tu d'autre ? Sachant qu'à l'issue du traitement du message un memset à "" est réalisé et que buffer est un char[256].
    Merci

  4. #4
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    recv renvoie le nombre d'octets lus.

  5. #5
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par GoldenEye Voir le message
    En revanche pour le strlen() > 1 (et non zéro), que proposes-tu de moins stupide ? Sachant qu'à l'issue du traitement du message un memset à "" est réalisé et que buffer est un char[256].
    Un memset(), c'est pas gratuit.

    http://emmanuel-delahaye.developpez....eaux.htm#texte

  6. #6
    Expert confirmé

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 033
    Billets dans le blog
    12
    Par défaut
    Déjà comme dit loufoque, recv renvoit le nombre d'octets lus, donc pas besoin de tester la taille du buffer.
    Je me demandais, pourquoi tu mets tes thread en THREAD_PRIORITY_BELOW_NORMAL?
    Si vous ne trouvez plus rien, cherchez autre chose...

    Vous trouverez ici des tutoriels OpenGL moderne.
    Mon moteur 3D: Castor 3D, presque utilisable (venez participer, il y a de la place)!
    Un projet qui ne sert à rien, mais qu'il est joli (des fois) : ProceduralGenerator (Génération procédurale d'images, et post-processing).

  7. #7
    Membre confirmé

    Profil pro
    Inscrit en
    Mars 2002
    Messages
    115
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 115
    Par défaut
    Merci les chefs, j'ai viré le strlen et le memset et c'est effectivement bien plus performant
    Si je mets une priorité supérieure, l'OpenGL perd trop en fps et en fluidité
    Merci encore

  8. #8
    Expert confirmé

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Billets dans le blog
    3
    Par défaut
    Moi déjà ... je comprends pas tu fonctionnes en "non-bloquants"....
    Et c'est pas un strlen/memset à chaque reception d'un paquet qui devrait diminuer ton frame-rate !!!
    Je dirai même au contraire, si le jeu est "temps-reel réseau", la priorité des threads de gestion de réseau devrait être plus élevée que le reste... l'affichage (comme le son par exemple), n'est qu'accessoire au bon déroulement d'une partie !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    while(1)    
    {
        if (recv(socket, buffer)>0) 
           Traitement(buffer);
    }
    Ca c'est horrible (et ca va manger tout un core CPU à priori)...
    D'ailleurs, à priori, si tu mets le socket en mode bloquant ca fera *exactement* le même résultat...


    Coté serveur, on a le même probleme....
    Utilises la fonction select pour choisir d'être "reveillé" quand un des sockets a reçu des données...

  9. #9
    screetch
    Invité(e)
    Par défaut
    passe juste tes sockets en bloquant.....

    et mets tes threads avec priorites maximales - 1. Ils sont sensés etre tout le temps en train de dormir, en attendant des données. donc passes tes sockets en bloquantes et attends que quelque chose se passe, ne mets pas des threads qui vont bouffer du CPU en permanence.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 12/10/2004, 13h04
  2. Performance des vertex array
    Par Mathieu.J dans le forum OpenGL
    Réponses: 13
    Dernier message: 25/06/2004, 10h47
  3. connection/deconnection des sockets
    Par yotasse dans le forum Développement
    Réponses: 3
    Dernier message: 17/02/2004, 12h08
  4. probleme de gestion de clients avec des sockets....
    Par ludvo dans le forum Réseau
    Réponses: 6
    Dernier message: 25/09/2003, 12h37
  5. utilisation des sockets sous windows
    Par Tupac dans le forum Réseau
    Réponses: 2
    Dernier message: 21/12/2002, 18h24

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo