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 :

Communication entre 2 programmes


Sujet :

C

  1. #1
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2014
    Messages
    82
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2014
    Messages : 82
    Par défaut Communication entre 2 programmes
    Bonjour,

    J'ai un problème je voudrais réaliser deux programmes qui communiquent entre eux mais je ne sais pas comment faire, en gros je lance un programme qui tourne pendant X temps jusqu’à ce que je lance le deuxième programme qui doit juste dire au premier programme de s’arrêter, donc en gros je dois juste passer à 1 par exemple une variable du premier programme quand le deuxième programme se lance.

    Mais je sais pas du tout comment m'y prendre. J'ai entendu parler des tubes mais je sais pas trop ce que c'est?

    Je suis sous Windows.

    Merci d'avance pour vos réponses

  2. #2
    Membre Expert
    Avatar de imperio
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    881
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

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

    Informations forums :
    Inscription : Mai 2010
    Messages : 881
    Par défaut
    Je trouve que les pipes ne sont pas le meilleur moyen pour communiquer entre 2 programmes mais qu'importe. En gros un pipe est généralement fait entre un processus père et un processus fils. Le père fork et puis ouvre un pipe. De son côté, le fils ouvre aussi un pipe puis fait ce qu'il à faire. Sache que tu peux rediriger les flux (comme écrire sur la sortie standard) dans ce pipe avec les fonctions de la famille dup.

    La solution que je préfère pour communiquer entre 2 programmes restent tout de même les sockets. Facile à mettre en place et il n'y a pas d'attente lorsque c'est fait en local. Cependant, sache qu'il existe aussi les fifo (seulement sous linux) et les messages queues. Si tu te sens vraiment d'attaque, tu peux même utiliser les signaux, mais ce n'est pas du tout fait pour ça (et ça ne fonctionne que sous linux encore une fois).

    Bref, voilà quelques pistes.

  3. #3
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2014
    Messages
    82
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2014
    Messages : 82
    Par défaut
    D'accord merci pour ta réponse mais avec les sockets je ne vois pas trop comment faire...je sais envoyé des données a un API avec ce code:
    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
        WSADATA WSAData;
        WSAStartup(MAKEWORD(2,0), &WSAData);
        SOCKET sock;
        SOCKADDR_IN sin;
        sin.sin_addr.s_addr	= inet_addr("192.168.0.10");
        sin.sin_family		= AF_INET;
        sin.sin_port		= htons(502);
        sock = socket(AF_INET,SOCK_STREAM,0);
        bind(sock, (SOCKADDR *)&sin, sizeof(sin));
        connect(sock, (SOCKADDR *)&sin, sizeof(sin));
     
        char Trame[1]={0x01};
        char buffer[255];
        send(sock, Trame, 1, 0);
        recv(sock, buffer, sizeof(buffer), 0);
        printf("%d",buffer[6]);
     
        WSACleanup();
    Donc pour faire en local sa doit la même chose environ je pense,
    Mais après dans le code ou je doit réceptionner la donné que j'envoie comment je fais pour exécuter un événement a la réception de ma donné?

  4. #4
    Membre Expert
    Avatar de imperio
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    881
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

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

    Informations forums :
    Inscription : Mai 2010
    Messages : 881
    Par défaut
    C'est pas les tutos qui manquent sur le net concernant les sockets...

  5. #5
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 150
    Par défaut
    Bonjour,

    Pourquoi ne pas utiliser les signaux ?

    • Dans le premier programme, tu créés un handler de signal, qui change la valeur de ta variable si le programme reçoit le signal SIGUSR1 par exemple.
    • Dans le second programme, au démarrage, tu cherches le PID du premier programme, et tu lui envoies le signal SIGUSR1, et le tour est joué.


    Comme tu le vois, la difficulté réside plus dans le fait de trouver le PID du premier programme que dans la gestion des signaux elle-même, notamment car cela va dépendre de l'OS que tu utilises. Sous Linux, tu peux appeler la commande ps, ou bien regarder le contenu de /proc. Sous Windows, je ne sais pas ce qui existe.
    Sinon, c'est moche mais efficace, tu modifies le premier programme pour qu'il écrive son PID quelque part : dans un fichier, dans une mémoire partagée, ...

    Bien sûr, tu peux aussi utiliser d'autres méthodes, mais celle-ci est très bien adaptée à ce que tu veux faire.
    "La route est longue, mais le chemin est libre" -- https://framasoft.org/
    Les règles du forum

  6. #6
    Membre Expert
    Avatar de imperio
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    881
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

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

    Informations forums :
    Inscription : Mai 2010
    Messages : 881
    Par défaut
    Mouais, je trouve ça un peu hasardeux. Au moins avec les sockets, tu écris un code et c'est fini. Après il y a toujours d'autres possibilités mais je trouvais que c'était la plus élégante.

  7. #7
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2014
    Messages
    82
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2014
    Messages : 82
    Par défaut
    Ouais je vais plutôt partir sur les sockets qui me semble plus facile a mettre en place.

  8. #8
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 150
    Par défaut
    Citation Envoyé par imperio Voir le message
    Mouais, je trouve ça un peu hasardeux.
    Je ne vois vraiment pas ce qu'il y a d'hasardeux dans l'utilisation des signaux.... Le principe même d'un signal est de prévenir un autre programme, c'est à dire exactement ce qui est demandé ici.

    Au moins avec les sockets, tu écris un code et c'est fini.
    Quelle différence avec les signaux ?

    Après il y a toujours d'autres possibilités mais je trouvais que c'était la plus élégante.
    Je trouve que gérer des sockets pour finalement ne rien envoyer, c'est super lourd. Et puis bien sur tu as toujours le problème du choix du port : dans une version "pro" d'un logiciel, celui-ci est configurable afin de pouvoir s'assurer qu'il n'y ait pas de conflits (ce qui arrive plus souvent qu'on ne croit), donc tu as exactement le même problème qu'avec les PID.

    Sinon, un très bon tuto sur les sockets : http://beej.us/guide/bgnet/output/ht...age/bgnet.html
    "La route est longue, mais le chemin est libre" -- https://framasoft.org/
    Les règles du forum

  9. #9
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2014
    Messages
    82
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2014
    Messages : 82
    Par défaut
    Et les signaux sont plus efficace que les tubes? Car j'ai presque réussi avec les tubes et j'ai réussi avec les sockets.

  10. #10
    Membre Expert
    Avatar de imperio
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    881
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

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

    Informations forums :
    Inscription : Mai 2010
    Messages : 881
    Par défaut
    @gangsoleil: ce que je reproche à ta solution, c'est qu'il est nécessaire de connaître le pid du programme visé. On peut l'afficher avec getpid() au lancement du programme, mais ça demande à l'utilisateur de le rentrer lui-même. Là j'ai l'impression qu'il souhaite que les deux programmes n'en aient pas besoin de cette interaction.

  11. #11
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 150
    Par défaut
    Citation Envoyé par imperio Voir le message
    @gangsoleil: ce que je reproche à ta solution, c'est qu'il est nécessaire de connaître le pid du programme visé. On peut l'afficher avec getpid() au lancement du programme, mais ça demande à l'utilisateur de le rentrer lui-même.
    Une solution :

    ATTENTION, programmes absolument non testes, ils sont certainement bourres de faute de frappes et d'erreurs

    programme 1 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    pid_t mypid;
    FILE * myfile;
     
    mypid = getpid();
     
    myfile = fopen ("/tmp/pid_du_programme1.txt", "w");
    /* verification de l'open */
    fwrite (myfile, "%ld", (long)mypid);
    fclose (myfile);
    programme 2 :
    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
     
    pid_t pid_prog1;
    FILE * myfile;
     
    myfile = fopen ("/tmp/pid_du_programme1.txt", "r");
    /* verification de l'open */
    fread (myfile, "%ld", (long)mypid);
    fclose (myfile);
     
     
    /* plus loin */
    errno = 0;
    ret = kill (pid_prog1, SIGUSR1);
    /* traitement du retour */
     
    /* ... */
    "La route est longue, mais le chemin est libre" -- https://framasoft.org/
    Les règles du forum

  12. #12
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2014
    Messages
    82
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2014
    Messages : 82
    Par défaut
    Merci pour ton exemple de code gangsoleil, il y a des erreurs au niveau de fwrite et fread faut que je regarde pourquoi.
    J'ai compris ton premier programme en gros tu viens écrire dans un fichier texte sont mypid et tu le récupères au début du programme 2 mais par contre je n'ai pas compris cette partie... :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    /* plus loin */
    errno = 0;
    ret = kill (pid_prog1, SIGUSR1);
    /* traitement du retour */
     
    /* ... */
    Si tu peut m’expliquè? Merci

  13. #13
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 150
    Par défaut
    La command kill() permet d'envoyer un signal. Son protoype est kill (pid_t pid, int sig), c'est à dire qu'elle prend en premier argument le PID auquel envoyer le signal, et en second le numéro du signal à envoyer. Ici, j'envoie le signal SIGUSR1 au pid contenu par la variable pid_prog1.

    Pour les erreurs, j'ai oublié de préciser la taille à lire/écrire, et j'ai mis les arguments dans le désordre...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
           size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
     
           size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
    "La route est longue, mais le chemin est libre" -- https://framasoft.org/
    Les règles du forum

  14. #14
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2014
    Messages
    82
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2014
    Messages : 82
    Par défaut
    D'accord merci j'ai compris, par contre comment je récupère le signal dans mon programme 1?

  15. #15
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 150
    Par défaut
    Hello,

    Tu le récupères grâce à des fonctions spécifiques, comme sigaction ou signal par exemple.

    Exemple de gestion de signal très très simple -- ATTENTION, code non testé, qui contient donc des fautes.

    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <signal.h>
     
     
    int loop_counter;
     
    static void
    handler(int sig, siginfo_t *si, void *unused)
    {
        loop_counter = 1;
    }
     
    int
    main(int argc, char *argv[])
    {
        char *p;
        int pagesize;
        struct sigaction sa;
     
     
      sa.sa_flags = SA_SIGINFO;
      sigemptyset(&sa.sa_mask);
      sa.sa_sigaction = handler;
      errno = 0;
     
      if (sigaction(SIGUSR1, &sa, NULL) == -1)
      {
         printf ("sigaction error %d %s", errno, strerror (errno));
      }
     
      loop_counter = 0;
      while (loop_counter == 0)
      {
        printf ("coucou\n");
        sleep (1);
      }
     
      return EXIT_SUCCESS;
    }
    "La route est longue, mais le chemin est libre" -- https://framasoft.org/
    Les règles du forum

  16. #16
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2014
    Messages
    82
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2014
    Messages : 82
    Par défaut
    Merci j'essaierai ça lundi ^^

  17. #17
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2014
    Messages
    82
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2014
    Messages : 82
    Par défaut
    Bonjour,

    J'ai un problème avec l'utilisation des fwrite et fread...je n'arrive pas à récupérer quelque chose avec mon fread...
    Voilà mon code :
    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <signal.h>
     
    int main()
    {
        pid_t mypid;
        FILE * myfile;
        pid_t pid_prog1;
     
        mypid = getpid();
     
        myfile = fopen ("pid_du_programme1.txt", "w+");
        /* verification de l'open */
        printf("mypid=%d\n",mypid);
        fwrite (&mypid, sizeof(mypid), 1, myfile);
     
        fread (&pid_prog1,sizeof(pid_prog1),1,myfile);
     
        printf("mypid=%d\n",pid_prog1);
     
        fclose (myfile);
    return 0;
    }
    Merci pour vos réponses.

  18. #18
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 150
    Par défaut
    Bonjour,

    Tu ouvres le fichier, puis tu écris X chiffres dedans. Le curseur de ton fichier est donc à la position X. Puis tu lis, à partir de cette position X, un chiffre...

    En fait, comme souvent, le problème que tu as ne vient que de ton exemple, et n'aurait pas eu lieu si tu avais fait un vrai programme qui écrit d'un côté, et un autre qui lit par ailleurs

    Code qui fonctionne :
    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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <signal.h>
    #include <sys/types.h>
    #include <unistd.h>
     
     
    int main()
    {
      pid_t mypid;
      FILE * myfile;
      pid_t pid_prog1;
     
      mypid = getpid();
     
      myfile = fopen ("pid_du_programme1.txt", "w+");
      /* verification de l'open */
      printf("mypid=%d\n",mypid);
      fwrite (&mypid, sizeof(mypid), 1, myfile);
      fclose (myfile);
     
      myfile = fopen ("pid_du_programme1.txt", "r");
     
      fread (&pid_prog1,sizeof(pid_prog1),1,myfile);
     
      printf("mypid=%d\n",pid_prog1);
     
      fclose (myfile);
      return 0;
    }
    "La route est longue, mais le chemin est libre" -- https://framasoft.org/
    Les règles du forum

  19. #19
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2014
    Messages
    82
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2014
    Messages : 82
    Par défaut
    Merci de ta réponse, maintenant j'ai un problème avec la fonction kill qui ne fonctionne pas... Mais j'ai réussi à faire ce que je voulais avec les pipes donc c'est bon mais ça pourrait toujours servir à quelqu'un d'autre si tu as la solution

  20. #20
    Membre Expert
    Avatar de imperio
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    881
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

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

    Informations forums :
    Inscription : Mai 2010
    Messages : 881
    Par défaut
    Voici les deux seules erreurs que peut rencontrer kill :
    1. Le pid donné n'existe pas.
    2. Le signal donné n'existe pas.

Discussions similaires

  1. communication entre deux programmes
    Par Invité dans le forum C
    Réponses: 19
    Dernier message: 12/10/2008, 13h07
  2. communication entre un programme et un service
    Par dvince38 dans le forum C++
    Réponses: 4
    Dernier message: 28/01/2008, 11h42
  3. Communication entre 2 programmes
    Par ophalia dans le forum C#
    Réponses: 10
    Dernier message: 20/08/2007, 17h48
  4. Débutant, Communication entre deux programmes
    Par Madalen dans le forum Langage
    Réponses: 5
    Dernier message: 23/05/2007, 23h27
  5. Communication entre 2 programmes (débutant)
    Par mandaillou dans le forum C++
    Réponses: 43
    Dernier message: 12/12/2006, 22h54

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