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

Réseau C Discussion :

Multi-thread portable


Sujet :

Réseau C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Par défaut
    Citation Envoyé par Médinoc
    Citation Envoyé par CSoldier
    Car pour moi, si je boucle dans la fonction par exemple avec un truc du style while (1) ..., bah tu crois que les autres threads arrivont a utiliser la fonction ?
    OUI. C'est le principe des threads, ils s'exécutent EN MÊME TEMPS. contrairement à de la programmation événementielle mono-threadée.

    Pour ce qui touche aux données, le seul truc c'est que les threads accederont a une liste chainees qui dans chaque element aura une adresse d'une structure allouée dynamiquement, structure dans laquelle se trouve des infos sur le serveur, socket sur lequelle travailler, etc...
    1° Ils ont chacun leur propre liste, ou bien est-elle partagée ? (c'est à toi de décider cela selon le fonctionnement de ton programme). S'ils ont chacun la leur, pas de problème.
    2° Si elle est partagée, est-ce qu'ils la modifient ? Si ils ne font que la lire, aucun problème. S'ils peuvent la modifier, tu dois utiliser un mutex (EXclusion MUTuelle) pour les empêcher de toucher à la liste en même temps (il ne faut pas qu'un thread la lise pendant qu'un autre la modifie)
    En fait c'est une liste unique, chaque element correspond a une connection sur un serveur ou un channel avec toutes les infos possible, compris une reference du thread lui meme (au cas où on sait jamais) et aucune modification ne se fait au sein des données, que de la lecture !
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  2. #2
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Par défaut
    En fait, les seuls changement qui se feront dans la liste, c'est au moment d'une nouvelle connection et ou deconnection ... donc dans ce cas, ajout ou suppression d'un element dans la liste mais sinon c'est tout, et là ce ne sera pas les thread qui le feront (du moins pour la connection, pour la deco c'est pas encore sur, je pense que si le thread se termine, c'est dans le cas de mon programme qu'une connection est finie donc à priori un thread pourra lancer la fonction qui se charge de ca !)

    D'ailleurs, je pensais a faire qu'un seul Thread qui serais lancé au debut du programme jusqu'à la fin et qui boucle sur toute la liste et verifie les messages de chaque serveurs et channels ! Ce ne serais pas une meilleure solution que de faire un thread par connection ?
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  3. #3
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    eh bien, pour la façon, je ne sais pas trop.
    Mais s'il y a modification de la liste pendant que les threads tournent, il faudra utiliser de la synchonisation si ceux-ci sont capables de parcourir la liste.

    Que font tes threads exactement? lire uniquement les informations qui LEUR sont relatives, ou bien font-ils des lectures complètes de la liste?

    S'ils ne lisent chacun qu'un seul élément, ils ne sont même pas forcés d'accéder au chaînage (utiliser une structure chaînée contenant une structure de données et passer au thread un pointeur vers la structure de données interne).
    Sinon, cela promet d'être plus compliqué.

    Sinon, il est également possible de faire tout un serveur en monothreadé, voir le topic "un ou plusieurs threads" vers la fin (solutions monothreadées avec select())
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  4. #4
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Par défaut
    Citation Envoyé par Médinoc
    eh bien, pour la façon, je ne sais pas trop.
    Mais s'il y a modification de la liste pendant que les threads tournent, il faudra utiliser de la synchonisation si ceux-ci sont capables de parcourir la liste.
    En fait, ils ne lisent que l'element qui les concernent !

    Citation Envoyé par Médinoc
    Que font tes threads exactement? lire uniquement les informations qui LEUR sont relatives, ou bien font-ils des lectures complètes de la liste?
    Ils lisent certaines données qui leur sont relatives et receptions de messages des serveurs distants et des channels, ils peuvent egalement envoyer de message du style une reponse a un PING d'un serveur mais ca s'arrete là !

    Citation Envoyé par Médinoc
    S'ils ne lisent chacun qu'un seul élément, ils ne sont même pas forcés d'accéder au chaînage (utiliser une structure chaînée contenant une structure de données et passer au thread un pointeur vers la structure de données interne).
    Pour ce on est d'accord, mais de toutes facons, le code va encore changer, je doit réorganiser certaines choses et mieux le faire !

    Citation Envoyé par Médinoc
    Sinon, il est également possible de faire tout un serveur en monothreadé, voir le topic "un ou plusieurs threads" vers la fin (solutions monothreadées avec select())
    Moi je fait un client IRC tout simplement, pas de serveur donc pas pour moi

    Je pense quand meme que faire un seul thread qui gere toutes les connections serais moins lours a gérer mais là, c'est presque une question existentielle que je me pose
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  5. #5
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    Moi je fait un client IRC tout simplement, pas de serveur donc pas pour moi
    Oups! oubli.
    J'avais oublié que les clients aussi pouvaient avoir plusieurs connexions (enfin, eux aussi peuvent marcher en mono-threadé avec select() dans ce cas-là)
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  6. #6
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Par défaut
    Quel est le role de la fonction selec ? Elle me serais utile si je fait un thread unique pour toutes les connections ?
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  7. #7
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    oui.

    select() permet de tester des descripteurs de fichiers OU des sockets (et rien d'autre) pour savoir notamment s'il y a des données à lire ("disponible en lecture") ou si la connexion a été fermée de l'autre coté ("condition d'exception")

    En testant smultanément "en lecture" tous les sockets ouverts, tu peux ensuite traiter les requêtes sur les sockets l'un après l'autre, puis à nouveau attendre que des données arrivent, etc.

    Une boucle d'attente sur select() est l'idéal pour une application réseau mono-threadée, ou une application qui gère tout le réseau dans un seul thread.

    Sous Windows, il y a également d'autres solutions non portables, mais toutes sont basées là-dessus.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  8. #8
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Par défaut
    Y'a pas des exemples d'utilisation de cette fonction, et voir meme plus ? Parceque, c'est pas que je n'y met pas de la volonté mais je ne suis pas plus avancé là, meme si cette discussion n'a pas du tout été stérile mais j'aurais aimé voir du concret pour voir comment on utilise tout ca !
    Et puis ca commence sérieusement à me gaver, ca fait que le 3° jours que je suis là dessus

    En tous je te remercie quand meme Medinoc
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  9. #9
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Par défaut
    Bon, j'ai un peu remanié mon code, fait du menage, ré-arangées certaines choses, voici le code de la fonction utilisé par le thread (j'ai opté pour un thread unique):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    void * foncs_messages_monitoring (void *p_data)
    {
       int numbytes;
       char s_buffer[MAX_BUF_SIZE];
       GtkTextBuffer *p_buffer = NULL;
       GtkTextIter i_end;
       gpointer p_st_data;
       _tab_s *p_tmp_tab_s = NULL;
       GList *p_list = NULL;
     
     
       /* -------------------------------------
          Reception et traitement des messages
       */
       int i;
       while (1)
       {
          G_LOCK (p_tab_srv_chan_list);
     
          if (p_tab_srv_chan_list != NULL)
          {
             /* On boucle sur toute la liste chainee */
             i = 0;
             for (p_list = g_list_first (p_tab_srv_chan_list);
                  p_list;
                  p_list = p_list->next)
             {
                /* On recupere la structure des widget */
                p_st_data = g_list_nth_data (p_list, i);
                p_tmp_tab_s = p_st_data;
     
     
                /* Reception d'un message */
                if ((numbytes = recv (p_tmp_tab_s->sock,
                                      s_buffer,
                                      MAX_BUF_SIZE,
                                      0)) < 0)
                {
                   perror ("recv");
                }
                else
                {
                   /* Verification du message. Si c'est un PING, on repond
                       par un PONG. Sinon, on affiche le message a l'ecran. */
                   s_buffer[numbytes] = '\0';
     
                   if (strncmp (s_buffer, "PING", 4) == 0)
                   {
                      strncpy (s_buffer, "PONG", 4);
     
                      /* Envoie de la reponse du PING */
                      if ((numbytes = send (p_tmp_tab_s->sock,
                                           s_buffer,
                                           strlen (s_buffer),
                                           0)) < 0)
                      {
                         perror ("send");
                      }
                      memset (&s_buffer, 0, sizeof (s_buffer));
                   }
                   else
                   {
                      gdk_threads_enter ();
     
                      /* Recupere le buffer de la zone de texte */
                      p_buffer = gtk_text_view_get_buffer (
                                     GTK_TEXT_VIEW (p_tmp_tab_s->p_text_view));
     
     
                      /* Affichage du message */
                      gtk_text_buffer_get_end_iter (p_buffer, &i_end);
                      gtk_text_buffer_insert (p_buffer, &i_end, s_buffer, -1);
     
                      gdk_threads_leave ();
     
                      memset (&s_buffer, 0, sizeof (s_buffer));
                   }
                }
     
     
                i++;
             }
     
     
             p_list = NULL;
             p_st_data = NULL;
             p_tmp_tab_s = NULL;
          }
     
          G_UNLOCK (p_tab_srv_chan_list);
          sleep (1);
       }
     
     
     
     
       return NULL;
    }
    Je voulais bloquer l'acces à la liste au programme tant que le thread n'aurait pas fini sont tour de boucle en utilisant les fonctions de GDK: G_LOCK et G_UNLOCK mais j'ai effet de bord assez bizzard à la compilation, voici un message d'erreur en les utilisant ainsi dans le code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    G_LOCK (p_tab_srv_chan_list);
    et le message:

    1134 C:\Documents and Settings\CSoldier\Mes documents\Sauvegardes\Programmation\MOPIC\mopic_foncs.c `g__p_tab_srv_chan_list_lock' undeclared (first use in this function)
    bizzard me direz-vous mais je ne vois pas quoi faire contre ca en fait donc je me suis un peu attarder sur les fonctions de bloquage et debloquage de phtread. J'ai un peu regardé le site d'Emmanuel qui traite justement de ce sujet mais moi contrairement a lui, je doit bloqué l'acces à la liste complete car lorsqu'une connection est en phase de s'etablir, ca ajoute un nouvel element dans la liste avec ecriture des infos etc...

    Comment je peut bloquer ma liste complete ?
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  10. #10
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    1°) Pour select, il y a un exemple qui est en train de prendre forme dans un topic voisin (j'ai pu le titre exact, mais il y a le mot Tchat dedans)
    2°) Tu utilises les threads posix, alors pouquoi ne pas utiliser les fonctions de mutex posix ? (cherche du coté de pthread_mutex_create(), pthread_mutex_lock())
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  11. #11
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Par défaut
    Deja cherché du coté des fonctions POSIX mais j'y pige que dal' ! J'ai meme vu un code sur le site d'Emmanuel qui traite de ce sujet mais moi je doit bloquer une liste complete donc je veut des expliquations ! Ca fait juste 2 jours que je bute sur ce sujet .....
    Merci pour le topic, vais essayer de le retrouver, en espérant que ca puisse m'aider au moins un peu
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  12. #12
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Par défaut
    Est-ce que le développement d'un serveur et d'un client se font de la meme maniere ? Car sinon, bah non ca me sert pas a grand chose, de plus je veut pas betement recopier mais je veut des explication claires et précises, l'ordre des choses, comment utiliser telle ou telle fonction, comment bloquer l'acces à ma liste et la débloquer (POSIX ou GDK, peu importe mais quelques chose qui marche) ... moi sur le net je ne trouve rien de rien ou bien c'est tres tres maigre
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  13. #13
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    Généralement, un serveur et un client sont complètement différents, mais comme ton client a plusieurs sockets actifs, son comportement devient très similaire à celui d'un serveur sans socket d'écoute.

    Bref, en excluant toute la partie avec le socket d'écoute, il reste:
    * Le maintient d'une liste de sockets actifs, plus les deux fd_set (lecture et exception)
    * Le bouclage avec attente sur select()
    * Le traitement de chaque client dont l'appel à FD_ISSET renvoie une valeur non-nulle. (partie qui n'est pas encore dans le topic concerné, mais devrait s'y trouver sous peu)
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  14. #14
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Par défaut
    Ok mais j'aimerais qu'on me dise "sur mon code que j'ai fournit sinon ca sert à rien que j'en fournisse un" les parties que je doit modifier parceque pour le moment je suis paumé et ca m'ennerve ! Et bordel qu'on m'explique comment utiliser ces fonctions !

    Merci en tous de ta patience avec moi
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  15. #15
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    Ben en fait ton code, qui utilise des onfctions gtk en plus, j'ai du mal à le comprendre...

    Par contre, j'ai l'impression qu'il est tout sauf non-bloquant puisque tu essaies de lire chaque socket l'un après l'autre, avant de vérifier qu'il y a bien des données dedans... (et puis, je n'ai vu aucun appel à select(), même pas une ébauche...)
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  16. #16
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Par défaut
    Citation Envoyé par Médinoc
    Ben en fait ton code, qui utilise des onfctions gtk en plus, j'ai du mal à le comprendre...

    Par contre, j'ai l'impression qu'il est tout sauf non-bloquant puisque tu essaies de lire chaque socket l'un après l'autre, avant de vérifier qu'il y a bien des données dedans... (et puis, je n'ai vu aucun appel à select(), même pas une ébauche...)
    Bah GTK on s'enfout, le seul moment où j'en utilise dans cette fonction, c'est pour afficher des message recu dans la zone de texte adequate.
    Bah j'ai une boucle while car le thread doit durer tout au long de la vie du programme, et à chaque tour de boucle (while) il parcours la liste (for) qui correspond à chaque connections effectives ! Et dans chaque tour de boucle for, il regarde si un nouveau message est arrivé, si c'est un PING il repond pas un PONG pour eviter la deconnection de la part du serveur distant !

    Pour le select oui je sais, c'est normal, je ne sais pas comment l'utiliser et encore pire, je ne sait pas à quel endroit ou quel moment l'utiliser !
    Pourquoi je demande de l'aide à ton avis ?
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  17. #17
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    OK, alors on va essasyer un petit algo simple, et on ne va faire des tests qu'en lecture (tant pis pour la fermeture intempestive d'un socket par le correspondant. Après tout, on est client, c'est à nous de le fermer, et au serveur de le garder ouvert)

    Déjà, il nous faut un fd_set pour select() (un seul suffira pour l'instant)
    Ensuite, il nous faut une liste complète de tous les sockets connectés (dans ta liste chaînée par exemple)

    Il me semble que le fd_set doit être régénéré à chaque fois, donc à chaque itération de la boucle:
    {
    on remplit le fd_set à partir de la liste:
    On commence par l'initialiser à zéro.
    on ajoute chaque socket de la liste au fd_set avec la mecro FD_SET

    Ensuite, on appelle select(). en lui passant l'adresse de notre fd_set dans le premier pointeur (celui pour tester "en lecture");

    Puis, on parcourt à nouveau la liste: Pour chaque socket de la liste,
    { on regarde si on a reçu quelque chose dessus avec la macro FD_ISSET qui renvoit une valeur non-nulle s'il y a quelque chose à lire (bref, on fait un "if(FD_ISSET(liste[n]))")
    Et si le test est vrai, alors là seulement on peut faire un read() ou un recv() pour lire les données reçues, et si c'est un PING, répondre PONG
    }
    }

    voilà, c'est à peu près ainsi que ça fonctionne...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  18. #18
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Par défaut
    Bon ok, on avance à ptit pas
    J'ai fait d'apres ce que tu m'as dit, voici le code de ma fonction avec les ajouts:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    void * foncs_messages_monitoring (void *p_data)
    {
       int numbytes;
       char s_buffer[MAX_BUF_SIZE];
       GtkTextBuffer *p_buffer = NULL;
       GtkTextIter i_end;
       gpointer p_st_data;
       _tab_s *p_tmp_tab_s = NULL;
       GList *p_list = NULL;
       fd_set fd_read;
     
       /* -------------------------------------
          Reception et traitement des messages
       */
       int i;
       int ret;
       while (1)
       {
          FD_ZERO (&fd_read);
     
          for (p_list = g_list_first (p_tab_srv_chan_list);
               p_list;
               p_list = p_list->next)
          {
             p_st_data = g_list_nth_data (p_list, i);
             p_tmp_tab_s = p_st_data;
     
             FD_SET (p_tmp_tab_s->sock, &fd_read);
          }
     
     
          p_list = NULL;
          p_st_data = NULL;
          p_tmp_tab_s = NULL;
     
     
          if ((ret = select (0, &fd_read, NULL, NULL, NULL)) < 0)
          {
             perror ("select");
          }
          else if (p_tab_srv_chan_list != NULL)
          {
             /* On boucle sur toute la liste chainee */
             i = 0;
             for (p_list = g_list_first (p_tab_srv_chan_list);
                  p_list;
                  p_list = p_list->next)
             {
                /* On recupere la structure des widget */
                p_st_data = g_list_nth_data (p_list, i);
                p_tmp_tab_s = p_st_data;
     
     
                /* Reception d'un message */
                if (FD_ISSET (p_tmp_tab_s->sock, &fd_read))
                {
                   if ((numbytes = recv (p_tmp_tab_s->sock,
                                         s_buffer,
                                         MAX_BUF_SIZE,
                                         0)) < 0)
                   {
                      perror ("recv");
                   }
                   else
                   {
                      /* Verification du message. Si c'est un PING, on repond
                          par un PONG. Sinon, on affiche le message a l'ecran. */
                      s_buffer[numbytes] = '\0';
     
                      if (strncmp (s_buffer, "PING", 4) == 0)
                      {
                         strncpy (s_buffer, "PONG", 4);
     
                         /* Envoie de la reponse du PING */
                         if ((numbytes = send (p_tmp_tab_s->sock,
                                               s_buffer,
                                               strlen (s_buffer),
                                               0)) < 0)
                         {
                            perror ("send");
                         }
     
                         memset (&s_buffer, 0, sizeof (s_buffer));
                      }
                      else
                      {
                         gdk_threads_enter ();
     
     
                         /* Recupere le buffer de la zone de texte */
                         p_buffer = gtk_text_view_get_buffer (
                                        GTK_TEXT_VIEW (p_tmp_tab_s->p_text_view));
     
     
                         /* Affichage du message */
                         gtk_text_buffer_get_end_iter (p_buffer, &i_end);
                         gtk_text_buffer_insert (p_buffer, &i_end, s_buffer, -1);
     
     
                         gdk_threads_leave ();
     
                         memset (&s_buffer, 0, sizeof (s_buffer));
                      }
                   }
                }
     
                i++;
             }
     
     
             p_list = NULL;
             p_st_data = NULL;
             p_tmp_tab_s = NULL;
          }
     
     
          sleep (1);
       }
     
     
     
     
       return NULL;
    }
    Mais bon, j'ai un plantage à coup sûr !
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  19. #19
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    Ben la structure générale, ça a l'air d'être ça...

    Tu as quel genre de plantage?
    Tu as essayé de faire tourner le prog sous un debugguer ou simplement d'afficher des messages sur stderr pour voir où ça plantait? (enfin, si tu as un stderr)

    PS: Tu devrais te faire une fonction pour l'affichage (et la tester) pour pouvoir afficher des messages gtk plus simplement dans ton code... Surtout pour le débogage...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  20. #20
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Par défaut
    Le problème apparement viens du select !
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

Discussions similaires

  1. Tri multi-threadé
    Par Tifauv' dans le forum C
    Réponses: 8
    Dernier message: 28/06/2007, 09h00
  2. multi-threading portable
    Par delfare dans le forum C
    Réponses: 4
    Dernier message: 22/02/2006, 16h09
  3. Réponses: 16
    Dernier message: 30/01/2004, 11h05
  4. [VB6][active x] faire du multi-thread avec vb
    Par pecheur dans le forum VB 6 et antérieur
    Réponses: 9
    Dernier message: 20/05/2003, 12h01
  5. [Kylix] exception qtinft.dll et multi-threading
    Par leclaudio25 dans le forum EDI
    Réponses: 3
    Dernier message: 27/03/2003, 18h09

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