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 :

MYSQL Client C utilisant WINSOCK uniquement


Sujet :

Réseau C

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2007
    Messages
    3
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 3
    Points : 2
    Points
    2
    Par défaut MYSQL Client C utilisant WINSOCK uniquement
    Bonjour,

    Je suis en train de développer un système d'information en Visual C/C++. Il s'agit d'un système complexe composé de magasins (boutiques) avec un serveur par magasin et d'un serveur dédié sur Internet pour synchroniser les stocks et permettre de gérer entre autre un catalogue global.

    J'ai déjà développé pas mal de choses et il ne me reste plus qu'un problème. Mes bases de données sont en MySQL et pour le moment j'utilise le client en c de MySQL. Le problème c'est que je ne peux pas placer d'évènement FD_CLOSE pour détecter une éventuelle déconnexion entre un magasin et le serveur internet. (Si on peut le faire et que je ne l'ai pas vu le problème s'arrête ici )

    Dans le cas contraire, je cherche donc un code-source "propre" et simple de connexion à une base MySQL utilisant Winsock et non des pipes des sockets unix...
    J'ai bien pensé à prendre le code MySQL mais c'est tellement le bordel que j'hésite un peu, mais si je n'ai pas le choix je partirai là dessus.

    J'aimerai votre avis?

    Cordialement
    Arnaud

  2. #2
    Membre expérimenté
    Avatar de granquet
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2005
    Messages
    1 201
    Détails du profil
    Informations personnelles :
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2005
    Messages : 1 201
    Points : 1 421
    Points
    1 421
    Par défaut
    quel est le probleme des sockets unix?

    la seule difference avec les sockets windows ...
    ben ... y'en as pas

    ha si ... sous windows faut "lancer" le merdier ... (WSAStart etc ...)

    la libMySql est hyper bien foutue et fait tout ce qu'il faut ... comme il faut ...

    et en plus, avec 3 petits #ifdef (un pour les includes, 1 pour le Close//fclose et un pour le WSAStartmachin), tu peux ecrire du code fonctionnel sous linux ...

    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
    #ifdef WIN32
    #include <winsock.h>
    typedef unsigned int u_int32_t;
    typedef size_t socklen_t;
    #elif defined(linux)
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <netdb.h>
     
    #define closesocket(a) close(a)
    #define SOCKET_ERROR (-1)       // defined in winsock.h
    typedef struct sockaddr_in SOCKADDR_IN;
    #endif
     
    int
    my_sock_init (void)             // init for winsock
    {
    #ifdef WIN32
      WSADATA wsaData;
      WORD verreq;
      verreq = MAKEWORD (2, 2);
      if (WSAStartup (verreq, &wsaData) != 0)
        return -1;
    #endif
      return 0;
    }
     
    int 
    my_sock_close(void) {
    #ifdef WIN32
     return WSACleanup(); 
    #else
      return 0;
    #endif
    }
    moi je dis que ce serait bete de se priver
    click my www
    ............|___
    ...................\
    .................._|_
    ..................\ /
    ..................."

  3. #3
    Membre éprouvé

    Profil pro
    Inscrit en
    Août 2003
    Messages
    878
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 878
    Points : 1 067
    Points
    1 067
    Par défaut
    Citation Envoyé par Dark_Ebola
    [...]
    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
    #ifdef WIN32
    #include <winsock.h>
    typedef unsigned int u_int32_t;
    typedef size_t socklen_t;
    #elif defined(linux)
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <netdb.h>
     
    #define closesocket(a) close(a)
    #define SOCKET_ERROR (-1)       // defined in winsock.h
    typedef struct sockaddr_in SOCKADDR_IN;
    #endif
    int
    my_sock_init (void)             // init for winsock
    {
    #ifdef WIN32
      WSADATA wsaData;
      WORD verreq;
      verreq = MAKEWORD (2, 2);
      if (WSAStartup (verreq, &wsaData) != 0)
        return -1;
    #endif
      return 0;
    }
    moi je dis que ce serait bete de se priver
    De se priver de WSACleanup() ?
    Un problème bien exposé
    est, pour moitié, solutionné. / La connaissance s'accroît quand on la partage, pas quand on l'impose. / La violence est le langage des faibles.

  4. #4
    Membre expérimenté
    Avatar de granquet
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2005
    Messages
    1 201
    Détails du profil
    Informations personnelles :
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2005
    Messages : 1 201
    Points : 1 421
    Points
    1 421
    Par défaut
    Citation Envoyé par David.Schris
    De se priver de WSACleanup() ?
    corrigé
    click my www
    ............|___
    ...................\
    .................._|_
    ..................\ /
    ..................."

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Pas de Wi-Fi à la maison : CPL

  6. #6
    Membre éprouvé

    Profil pro
    Inscrit en
    Août 2003
    Messages
    878
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 878
    Points : 1 067
    Points
    1 067
    Par défaut
    Citation Envoyé par Dark_Ebola
    corrigé
    Citation Envoyé par Dark_Ebola
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    /* [...] */
    int 
    my_sock_close(void) {
    #ifdef WIN32
     WSACleanup(); 
    #endif
      return 0;
    }
    [...]
    Si tu ne testes jamais la valeur retournée par WSACleanup(), alors pourquoi pas comme ceci ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #ifdef WIN32
    #define my_sock_close WSACleanup
    #else
    #define my_sock_close
    #endif
    PS : je ne dis pas que c'est mieux, je pose la question.
    Un problème bien exposé
    est, pour moitié, solutionné. / La connaissance s'accroît quand on la partage, pas quand on l'impose. / La violence est le langage des faibles.

  7. #7
    Membre expérimenté
    Avatar de granquet
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2005
    Messages
    1 201
    Détails du profil
    Informations personnelles :
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2005
    Messages : 1 201
    Points : 1 421
    Points
    1 421
    Par défaut
    Citation Envoyé par David.Schris
    Si tu ne testes jamais la valeur retournée par WSACleanup()
    c'est une erreur
    re-corrigé

    jvais aller me coucher moi ...
    click my www
    ............|___
    ...................\
    .................._|_
    ..................\ /
    ..................."

  8. #8
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2007
    Messages
    3
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 3
    Points : 2
    Points
    2
    Par défaut
    Salut,

    J'ai pas de problème avec les sockets UNIX mais je fais un projet complètement Win32 dans la mesure où c'est ce que j'ai comme OS sur les ordinateurs des magasins concernés.
    Et faire une interface GTK ca me tente pas pour le moment...

    Le problème ne réside pas dans les connexion Winsock! J'ai quelques années de Winsock, ça me pause pas de problème, mais faire un client MySQL c'est pas aussi simple.
    J'ai cru voir dans les sources que ce qui est utilisé c'est yaSSL, donc avec yaSSL peut on dialoguer avec la base? Est-ce le seul bloc nécessaire?

    Mon objectif c'est d'avoir du code clair et malheureusement je trouve que le code de la lib mysql n'est pas super clair entre autre à cause l'ambivalence (Win32 UNIX) qui leur est nécessaire me l'est pas!

    Merci

  9. #9
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 603
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    je ferais juste une remarque en passant..


    Dark_Ebola a écrit :

    quel est le probleme des sockets unix?

    la seule difference avec les sockets windows ...
    ben ... y'en as pas

    ha si ... sous windows faut "lancer" le merdier ... (WSAStart etc ...)
    .
    Je me permettrais d'attirer votre attention sur un point central de différence, que malheureusement bien peu de gens mettent en avant, et qui pourtant, dans ce monde de normes et d'objets et de séparation des couches, est crucial....

    Simplement : les sockets Windows violent le modèle en couche...

    Pourquoi leur faut-il un handle ? (et qui plus est pourquoi (et en lisant la doc système de Windows M$ est particulièrement fier de cette "feature") pour les messages (pour les sockets asynchrones) faut-il un handle de fenêtre ????? )

    Autrement dit pourquoi faudrait-il qu'un standard téléphonique connaisse le type de télphone avec lequel je me branche sur la prise ????

    C'est à mon avis une violation d'un élément central... Et personne n'a lair de s'en offusquer...
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par souviron34
    Pourquoi leur faut-il un handle ? (et qui plus est pourquoi (et en lisant la doc système de Windows M$ est particulièrement fier de cette "feature") pour les messages (pour les sockets asynchrones) faut-il un handle de fenêtre ????? )
    Bah, les sockets en asynchrone, ça se fait à coup de select() et de threads... C'est pas un problème et c'est portable.
    Pas de Wi-Fi à la maison : CPL

  11. #11
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 603
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Bah, les sockets en asynchrone, ça se fait à coup de select() et de threads... C'est pas un problème et c'est portable.
    mwé...

    Mais les sockets et les sockets aysnchrones étaient portables .. jsqu'à Winsock...
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par souviron34
    Mais les sockets et les sockets aysnchrones étaient portables .. jsqu'à Winsock...
    Je ne connais pas Winsock qui est obsolète, mais avec Winsock2, c'est pareil que sous unixoïde.

    A part l'initialisation (WSAtrucmuche()), la seule restriction est que select() ne traite pas autre chose que les sockets sous Windows.

    Un thread et c'est réglé. Ca reste portable.
    Pas de Wi-Fi à la maison : CPL

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Les "sockets asynchrones" de Winsock2 permettent à une fenêtre d'être notifiée d'un événement sur un socket (genre: Un client essayant de se connecter) par un simple message, comme elle est prévenue de tout le reste (souris, clavier).
    En fait, cela fait des événements sur un socket des événements comme les autres.
    C'est très intéressant sous Windows, car cela centralise toute l'attente dans le GetMessage(), alors qu'on serait obligé d'utiliser plusieurs threads sous unixoïde pour cumuler interface graphique et sockets.

    (Note: Les sockets asynchrones utilisent en fait un thread supplémentaire, mais c'est transparent et les fonctions utilisateur n'y ont pas accès : Tout le code utilisateur s'exécute dans le même thread).
    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
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 603
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    je ne comprend pas ce que vous dites tous les 2...

    Cela fait 12 ans que je programme des sockets sous Unix/HPUX et Linux, pour faire des serveurs et une bibliothèque sous-couche de fond pour une très grosse application avec plusieurs GUI.

    1) je n'ai jamais ententu parlé (sauf par des gens venant du côté Windows et allant vers Linux) de thread.

    2) ce n'est pas portable puisque les noms changent (WSA...)...

    3) tout l'intérêt de la structure asynchrone telle qu'elle est définie sous U.x est justement d'être INDEPENDANT de comment on l'utilise : comme pour la fonction signal, on passe un (void *)fonction a être appelé.... Il me semble avoir compris qu'avec Winsock2 il faut passer un handle de fenêtre.. Mais par exemple dans le cas de mes serveurs je n'ai PAS de fenêtres (ce sont des processus (vrais services sous U.X))..

    4) je pense que justement c'est un recul si on doit faire connaître à la couche basse quelque chose de la couche supérieure.

    Pour reprendre un peu mon exemple cité plus haut :

    J'ai un téléphone (fixe). Je le branche sur une prise. J'appelle un numéro au Japon. Je ne vois pas pourquoi MON téléphone devrait envoyer/connaître autre chose que les impulsions et les fréquences reconnues.. Il n'y a aucune raison pour que, afin de téléphoner, le CENTRAL ait besoin de connaître les caractéristiques de mon téléphone. Il connait juste le départ de ma ligne physique et le numéro attaché (pour nous le port), AU CENTRAL, et la série des fréquences que je lui envoie. Sans plus.

    Si maintenant je prend l'exemple de mon application centrale :
    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
                      Bibliothèque de communication <- HTTP(sockets)
    
                                /                     \
                               /                       \
                              /                         \
               Bibliothèque pour                  Bibliothèque de 
            fabriquer des serveurs              création de données
    
                           |                              |
                           |                              |
    
       Serveur1 Serveur2 Serveur3....           Bibliothèque "métier"
    (binaires lancés comme services)
    (sans fenêtres. C pur)                            /    \
                                                     /      \
                                                    /        \
    
                                    Bibliothèque GUI1      Bibliothèque GUI2
    
                                                   \         /
                                                    \       /
                                                     -------
                                                     /       \
                                            Application1   Application2 ....
                                                (binaires avec GUI)
    Pourquoi faudrait-il que la couche sockets connaisse un id d'une fenêtre de la couche GUI ???

    Ce que je dis c'est que la norme ISO de développement en couches est violée, et que ce n'est pas portable .

    Mes serveurs n'ont PAS de fenêtres, sous les sytèmes U.X. Et d'autre part mes applis n'interfacent QUE le GUI.... Et le GUI n'interface QUE la couche métier. Et la couche métier n'interface QUE la couche création de données, qui ,elle, interface la couche HTTP...

    De plus, si vous avez une solution pour que je ne fasse que recompiler et linker avec une autre bibliothèque, là je dis que c'est portable... Si il faut changer du code, ça ne l'est pas
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par souviron34
    je ne comprend pas ce que vous dites tous les 2...
    http://emmanuel-delahaye.developpez.com/reseaux.htm
    Pas de Wi-Fi à la maison : CPL

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    souviron34 : Dans le schéma que tu nous montre, ce n'est pas le serveur qui a une interface graphique, mais le client. Ton serveur est exclusivement serveur et ne fait rien d'autre.

    De plus, sous Unixoïde, un serveur peut avoir une interface texte (Command-line interface), parce que select() marche sur les flux standard, ce qui n'est pas le cas sous Windows.
    Les sockets Asynchrones sous Windows permettent de mettre dans le même processus l'interface graphique (donc, des fenêtres) et des fonctions serveur, sans avoir à gérer soi-même la synchronisation entre threads (puisque tout le code utilisateur s'exécute dans un et un seul thread).

    À présent, pourquoi un serveur aurait une interface utilisateur (texte ou grpahique) ? Pour l'instant, je ne vois qu'une raison valable: L'existence d'un protocole appelé "FTP actif", où le client FTP est lui-même un serveur (sans compter les clients-serveurs de P2P).
    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.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Pourquoi faudrait-il que la couche sockets connaisse un id d'une fenêtre de la couche GUI ???

    Ce que je dis c'est que la norme ISO de développement en couches est violée, et que ce n'est pas portable.
    Il n'est pas question ici de problèmes de couche: il est question de système, de programmation événementielle, et de regrouper l'attente en un seul point du thread.
    Cela est possible:
    • avec aucune interface utilisateur (tout par sockets)
    • avec une interface texte sous unixoïde (attente sur select())
    • avec une interface graphique et les sockets asynchrones de Win32 (attente sur GetMessage() ou une fonction soeur).

    Cela n'est pas possible (à ma connaissance) :
    • avec une interface texte sous Win32 (select() ne marche pas sur les flux standard)
    • avec une interface graphique sous unixoïde (ou bien si : Comme X-Window est en client-serveur, select() marche peut-être 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.

  18. #18
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 603
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Médinoc
    Il n'est pas question ici de problèmes de couche: il est question de système, de programmation événementielle, et de regrouper l'attente en un seul point du thread.
    Si justement...

    Ce que je veux dire, au cas où je me sois mal exprimé :

    J'ai une bibliothèque de manipulation de sockets (Start_Serveur, Start_Client, Ecoute_Synchrone, Ecoute_Asynchrone, Envoie_Asynchrone, Envoie_Synchrone, etc..)


    Encore une fois je répète je n'ai jamais eu besoin de la notion de thread... C'est uniquement un "wrapping" autour des fonctions standard de C (getpeername, gethostbyname, select, etc...)

    La FONCTIONALITE est une fonctionalité de base (gérer la communication), sans plus... (au même titre que "coder une fréquence pour la convertir en chiffre" présente dans les standards téléphoniques)..

    Maintenant je construit des applications différentes sur cette bibliothèque :

    1) des serveurs de données (sans interfaces. fonctionnants uniquement via requêtes d'un protocole du style HTML) (donc programmation évènementielle)
    2) un "interrogateur" de serveurs, avec une interface en mode texte, permettant de dialoguer avec les serveurs
    3) des applications interactives (avec interfaces fenêtres (XWindow pour l'instant, mais justement pourrait être Windows ou Java)) se connectant à des serveurs et demandant/affichant/renvoyant des données. Ces applications sont bien entendu également à programmation évènementielle.
    4) des applications non-interactives (avec interfaces, mais sans fenêtres (exemple : input : langage de commande, scripts; output : gif, jpeg..)) effectuant les mêmes fonctionalités que les applications interactives.

    Si je change d'outil graphique, un découpage fonctionnel me dit que la présentation n'est que ça, une présentation... La fonctionalité réside en dessous. Et l'accès aux données encore en dessous.. Et la gestion de la communication encore en dessous....(après il y a la gestion "kernel" des sockets (le code exact des select etc...)).

    Donc le fait de changer d'outil graphique ne devrait avoir AUCUN impact sur une couche basse...

    Je vous montre un exemple, justement avec la routine gérant la mise en asynchrone des sockets :

    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
     
     
    /*!
      ---------------------------------------------------------------------
       Nom      : <InitialiserSocketAsynchrone>
       Creation : xxxx - fevrier 1997
       But      : Initialiser l'option de lecture asynchrone pour un socket.
                  Lorsqu'un fichier est en mode asynchrone, le systeme avise le
                  programme appelant lorsque le fichier est pret pour une lecture.
     
       Parametres : 
           <requete>        : numero du descripteur de fichier 
           <fonction>       : fonction appelee lors de la reception du signal systeme
     
     
       Retour : 0 si tout va bien
                < 0 il y a eu erreur
                > 0 : il y a deja des caracteres a lire sur le socket.  Dans ce
                      cas, on retourne le nobre de caracteres disponibles sans 
                      passer en mode asynchrone.
     
       Remarques :
         Aucune
     
       Modifications :
     
          Nom         :
          Date        :
          Description :
      ----------------------------------------------------------------------
    !*/
     
    int InitialiserSocketAsynchrone(int requete,void (*fonction)()  )
    {
       pid_t pid;
       int retour;
     
       int bidon;
     
     
    #ifdef DEBUGJS
       fprintf (stderr, " ESSAI MISE SOKCET ASYNC");
    #endif
     
       /*
        *On verifie s'il y a des caracteres a lire sur le conduit
        *Si oui, on retourne le nombre de caracteres sans passer
        *en mode asynchrone
        *Ceci evite les interruptions lors de la lecture
        */
       retour = ioctl(requete,FIONREAD,&bidon);
       if ( retour != 0 )
         {
    #ifdef DEBUGJS
           fprintf (stderr, " PEUT PAS METTRE SOCKET ASYNC : %d ERREUR %d",requete,retour);
    #endif
           return(retour);
          }
       if(bidon > 0 )
         {
    #ifdef DEBUGJS
           fprintf (stderr, " PEUT PAS METTRE SOCKET ASYNC : %d reste qquechose a lire",requete);
    #endif
           return(bidon);
         }
     
       /*
        *Il n'y a rien a lire, on passe en asynchrone
        *Obtenir le numero de ce processus pour pouvoir le refiler
        *a ioctl afin d'etre avise de tout changement sur le socket
        */
     
       pid =getpid();
     
       bidon = (int) pid;
    #ifndef LINUX
       retour = ioctl(requete,SIOCSPGRP,&bidon);
    #else
       retour = fcntl(requete,F_SETOWN,(long)bidon);
    #endif
       if ( retour < 0 )
         return retour ;
     
       /*
        *Initialiser l'option asynchrone pour le socket
        */
    #ifdef DEBUGJS
       fprintf (stderr, " DECLENCHE");
    #endif
     
    #ifndef LINUX
       bidon = 1;
       retour = ioctl(requete,FIOASYNC,&bidon);
    #else
       bidon = O_ASYNC ;
       retour = fcntl(requete,F_SETFL,(long)bidon);
    #endif
     
    #ifdef DEBUGJS
       fprintf (stderr, " MISE SOCKET ASYNC : %d",retour);
       if ( retour < 0 )
         fprintf (stderr, " => ERREUR");
    #endif
     
       if ( retour < 0 )
           return retour ;
       else
         {
    #ifdef DEBUGJS
           fprintf (stderr, " DECLENCHE SIGIO");
    #endif
           signal(SIGIO,fonction);
     
          return (0);
         }
    }

    On voit bien ici que RIEN ne justifie la connaissance de l'UTILISATION.... La fonction appelée lors du SIGIO peut être n'importe quoi : une fonction d'interface, une fonction pure code, etc..

    Or donc cette routine est appellée dans les 4 cas cités plus haut (sans interface même texte, avec interface texte, avec interface graphique interactive, avec interface graphique non-interactive)...

    Ce que je veux dire, c'est que cela fait partie des appels reconnus par le standard C... et que c'est logique..

    Si maintenant je passe sous Windows avec Winsock2, je dois fournir une EXPLICATION de l'utilisation..... puisqu'il faut que je passe un handle...

    Cela correspond donc à ce que je dis, cela viole le modèle de couches indépendantes (où chaque couche est IGNORANTE de la couche au dessus, mais dépend de la couche en dessous....)
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Ton code sur les sockets asynchrones ne semble pas se baser sur une attente centralisée, mais sur des signaux, qui interrompent donc l'exécution potentiellement à n'importe quel moment. Ce n'est donc pas de la prorammation événementielle comme celle de Windows, mais un système basé sur l'interruption du flot de contrôle actuel.
    Cela suppirme la difficulté dans Windows qui consiste à ATTENDRE qu'il se passe quelque chose.
    Ou plus précisément, ATTENDRE des événements différents pouvant provenir de plusieurs sources différentes.

    Exemple:
    • Serveur sans interface, un seul type de source: sockets. --> Avec SIGIO tu fais ce que tu veux, avec select() ça marche aussi.
    • Serveur avec interface texte, un seul type de source aussi, car les sockets sont des descripteurs.
    • Serveur avec interface graphique dans le même processus, genre client FTP graphique : Ici, il y a deux sources d'événements : Les événements arrivant sur la fenêtre et ceux sur le réseau.
      En programmation événementielle, on attend en un seul point qu'un événement se passe. Problème, il faut avoir une fonction système pour ça. Si tu fais select(), la fenêtre ne réagira pas pendant le timeout. Si tu utilises la fonction d'attente d'un événement sur la fenêtre, tu ne réagiras pas aux sockets en programmation événementielle. Par contre, en programmation interruptible, tu peux attendre tranquillement un événement sur la fenêtre et être interrompu quand quelque chose arrive.

    Eh bien sous Windows, tu n'as pas de programmation socket interruptible comme ça. Tu n'as que des fonctions d'attente d'événements. Deux sont dédiées aux sockets et à rien d'autre: Ce sont select() et WSAWaitForMultipleEvents().
    D'autres sont dédiées aux événements d'une fenêtre : Ce sont GetMessage(), WaitMessage(), MsgWaitForMultipleObjects() et MsgWaitForMultipleObjectsEx(). Il semblerait qu'aucune de ces fonctions ne puisse attendre directement un événement sur un socket comme select() le fait. C'est pourquoi on doit utiliser une fonction qui traduit tout événement socket en message : WSAAsyncSelect() (comme select() asynchrone).
    Citation Envoyé par MSDN
    The WSAAsyncSelect function requests Windows message-based notification of network events for a socket.
    Sur cette fonction, il reste tout de même la faille que tu as précisée : La question "pourquoi destiner le message à une fenêtre en particulier et non à un thread en général ?" ne possède pas de réponse valide à ma connaissance. Mais de toute façon, la fenêtre en question n'a pas besoin d'être ton interface graphique. Cela peut être une fenêtre cachée en permanence, voire même une message-only window à partir de Win 2000 et supérieur.
    (d'ailleurs, par soucis de séparation, je vais en effet auditer mon code pour qu'il en soit ainsi, tiens).

    PS: Il n'est pas nécessaire en effet d'évoquer la notion de thread.
    Mais comme sous Windows, tout processus est composé d'un ou plusieurs threads, et comme toutes les fonctions d'attente interrompent le thread courant et non le processus courant (ce qui revient au même pour un processus mono-threadé), je parle d'attente "en un seul point du thread".
    Mais si le terme "thread" t'offense, j'aurais aussi pu dire "en un seul point du flot d'exécution". Ça te va?
    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
    Membre éprouvé

    Profil pro
    Inscrit en
    Août 2003
    Messages
    878
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 878
    Points : 1 067
    Points
    1 067
    Par défaut
    Citation Envoyé par souviron34
    [...] un protocole du style HTML [...]
    "HTML" : avec un "L" comme "Protocole"
    Un problème bien exposé
    est, pour moitié, solutionné. / La connaissance s'accroît quand on la partage, pas quand on l'impose. / La violence est le langage des faibles.

Discussions similaires

  1. Utiliser winsock sous Access
    Par Poile dans le forum Access
    Réponses: 4
    Dernier message: 28/09/2006, 14h05
  2. problème mysql-client
    Par baali_hacene dans le forum Installation
    Réponses: 2
    Dernier message: 18/05/2006, 15h44
  3. MySQL : client encoding
    Par Gruik dans le forum SQL Procédural
    Réponses: 5
    Dernier message: 15/05/2006, 15h18
  4. [Info]Application client/Serveur utilisant JDBC
    Par freaky_boy dans le forum JDBC
    Réponses: 2
    Dernier message: 10/03/2006, 19h13
  5. Réponses: 6
    Dernier message: 22/09/2005, 10h21

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