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 :

Comment faire communiquer deux process avec un named pipe


Sujet :

C

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2016
    Messages : 5
    Par défaut Comment faire communiquer deux process avec un named pipe
    Bonjour,

    Je suis un grand débutant en C, et pourtant je suis censé coder deux programmes qui échangent des données l'un avec l'autre.
    Et pour tout dire, je suis un peu perdu !
    De fait, je viens quérir de l'aide ici.

    Plus de détail sur ce que je cherche à accomplir :
    Un premier programme/process qui envoie un message quelconque au second.
    Un second prog/proc qui réceptionne ce message et l'affiche.
    (Le projet est plus conséquent, mais si j'arrive déjà à faire ça, je devrais m'en sortir pour la suite.)

    A priori, après quelques (beaucoup en fait) recherches, il ressort que j'ai besoin d'utiliser un named pipe.
    Pour le créer et l'utiliser, j'ai besoin de mkfifo, open, read and write.

    J'ai donc les outils, mais pas doué comme je suis, je n'arrive pas à les utiliser.

    Du coup, voilà ma demande :
    Est-ce que quelqu'un pourrait me montrer un exemple commenté pour faire ce fameux named pipe.

    Et tant que j'y suis, bonne année à tous !

    ----

    Edit : Déjà rien qu'avec ceci, je suis bloqué :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <fcntl.h>
     
    int main(void){
        const char* monTube = "essai.fifo";
     
        int mkfifo(monTube, 0644);
    }
    Le compilateur me dit "expected ')' before numeric constant" pour le 0644...

    en résumé : à l'aide !

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 442
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 442
    Par défaut
    Bonjour et bienvenue,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        int mkfifo(monTube, 0644);
    Il ne faut pas re-spécifier le type de la fonction quand tu ne cherches pas à la déclarer mais seulement à l'invoquer :

    Maintenant, pourquoi le compilateur ne t'as pas indiqué une erreur de syntaxe ou une redéfinition de fonction ? D'abord parce que tu n'as pas inclus les bons headers :

    Citation Envoyé par man 3 mkfifo
    NAME
    mkfifo, mkfifoat - make a FIFO special file (a named pipe)

    SYNOPSIS
    #include <sys/types.h>
    #include <sys/stat.h>

    … et ensuite parce que l'expression était correcte jusqu'à « int mkfifo » qu'il a pris pour une variable. Tu as fait suivre cette expression par quelque chose entre parenthèses qui aurait pu être valable. Le compilateur te fait donc confiance, jusqu'arrivé à la virgule où là, il n'y plus rien à en tirer. Mais comme il t'accorde le bénéfice du doute et que plusieurs variables du même type peuvent bel et bien être déclarées en les séparant par des virgules, il s'attendait à ce que l'expression soit dûment refermée avant de rencontrer celle-ci. Et c'est ce qu'il t'explique par ce message sibyllin.

  3. #3
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 800
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 800
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par mikamic Voir le message
    Du coup, voilà ma demande :
    Est-ce que quelqu'un pourrait me montrer un exemple commenté pour faire ce fameux named pipe.
    Bonjour

    Tu dois créer deux programmes (ou deux processus mais vu que tu débutes, on va pas te faire partir sur le fork() de suite)

    Le programme 1: il créee le fifo (enfin il n'est pas obligé si le fifo existe déjà), l'ouvre en écriture, écrit des données et le referme
    Le programme 2: il ouvre le fifo en lecture, lit les données et le referme (puis bien entendu il traite les données)

    Donc cela se traduit par
    p1
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <string.h>
    #include <fcntl.h>
     
    int main()
    {
    	int f;
    	mkfifo("fifo", 0644);
    	f=open("fifo", O_WRONLY);
    	write(f, "Hello World", strlen("Hello World") + 1 /* +1 pour y mettre aussi le '\0' */);
    	close(f);
    }

    p2
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #include <fcntl.h>
    #include <stdio.h>
     
    int main()
    {
    	int f;
    	char data[1000];
    	f=open("fifo", O_RDONLY);
    	read(f, data, 1000);
    	close(f);
    	printf("data=[%s]\n", data);
    }

    Tu peux les exécuter dans l'ordre que tu veux, le couple est atomique (l'exécution du premier est bloquée jusqu'à ce que l'autre programme soit exécuté).
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  4. #4
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2016
    Messages : 5
    Par défaut
    Merci à vous deux ! C'est déjà beaucoup plus clair.

    Quelques petites questions supplémentaires :
    -Qu'est-ce qui se passe si on ne ferme pas le pipe proprement, avec close ? N'est-ce pas fait par défaut à la fermeture du programme ?
    -Ne devrais-je pas supprimer mon fichier fifo, une fois le programme terminé ? Si oui, comment faire ?
    -Concernant les include, j'ai utilisé <unistd> et ça fonctionne. Est-ce qu'il remplace les include <sys> ?

    à bientot !

  5. #5
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 442
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 442
    Par défaut
    Citation Envoyé par mikamic Voir le message
    Merci à vous deux ! C'est déjà beaucoup plus clair.

    Quelques petites questions supplémentaires :
    -Qu'est-ce qui se passe si on ne ferme pas le pipe proprement, avec close ?
    Ça dépend de quel côté. Si tu oublies de le refermer côté rédacteur mais que le programme ne se termine pas, alors le programme en lecture risque d'attendre indéfiniment des données qui n'arriveront jamais.

    N'est-ce pas fait par défaut à la fermeture du programme ?
    Si, mais ce n'est pas propre de laisser le système faire le ménage à ta place.

    -Ne devrais-je pas supprimer mon fichier fifo, une fois le programme terminé ?
    Si. Sauf si ton tube nommé a vocation à rester en place et à servir de point de rendez-vous entre un dæmon serveur et ses clients, comme lp.

    Si oui, comment faire ?
    En effaçant le fichier de façon ordinaire, avec remove() (ou unlink() en programmation système UNIX)

    -Concernant les include, j'ai utilisé <unistd> et ça fonctionne. Est-ce qu'il remplace les include <sys> ?
    Non, ces différents fichiers ne se « remplacent » pas mutuellement, mais ils peuvent dépendre les uns des autres et, donc, s'inclure implicitement. L'usage veut cependant que l'on inclue tous les fichiers définissant les ressources ou fonctions que l'on utilise au moins une fois dans le fichier source et que l'on exclue tous les autres s'ils ne servent pas.

    Au passage, les headers en <std….h> signfient « Standard … », c'est-à-dire les ressources définies par la bibliothèque C standard indépendamment du système d'exploitation et <unistd.h> définit les ressources de base proposées par UNIX en particulier.

    Il est donc important de bien consulter les man pages des fonctions que l'on utilise pour être sûrs d'inclure les bons fichiers en fonction des ressources que l'on utilise et des systèmes d'exploitations (voire de leurs variantes) sur lequel on veut faire fonctionner son programme.

  6. #6
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2016
    Messages : 5
    Par défaut
    Merci pour ces explications, obsidian.

  7. #7
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2016
    Messages : 5
    Par défaut
    Bonsoir !
    J'ai un autre petit soucis qui se présente...

    Voilà mes deux fichiers lié par les named pipe (aussi disponible sur github) :

    pilote.c:
    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <sys/types.h>
    #include <sys/stat.h>
     
    #define TAILLE_MESSAGE 256
     
    int main(void){
    	int pipeToCore;
    	int pipeFromCore;
    	const char* pipePiloteToCore = "piloteToCore.fifo";
    	const char* pipeCoreToPilote = "coreToPilote.fifo";
     
    	char messageCore[TAILLE_MESSAGE];
    	char messagePilote;
     
    	mkfifo(pipePiloteToCore, 0644);
    	mkfifo(pipeCoreToPilote, 0644);
     
    	pipeToCore = open(pipePiloteToCore, O_WRONLY);
    	pipeFromCore = open(pipeCoreToPilote, O_RDONLY);
     
    	printf("Souhaitez-vous effectuer une requête ATIS (y/n)?\n");
    	//scanf("%s",&messagePilote);
    	do{
    		messagePilote = getchar();
    		if(messagePilote == 'y')
    			write(pipeToCore, &messagePilote, TAILLE_MESSAGE);
    		else if(messagePilote == 'n')
    			goto close;
    	}
    	while(messagePilote != 'y' && messagePilote != 'n');
     
     
    	read(pipeFromCore, messageCore, TAILLE_MESSAGE);
    		printf("%s", messageCore);
    	write(pipeToCore, "ACK 0", TAILLE_MESSAGE);
     
    	close:
    	return EXIT_SUCCESS;
    }
    tour.c:
    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <fcntl.h>
     
    #define TAILLE_MESSAGE 256
     
    int main(void){
    	int pipeFromPilote; //depuis le pilote
    	int pipeFromMeteo; //depuis la meteo
    	int pipeToPilote; //vers le pilote
    	const char* tubePiloteToCore = "piloteToCore.fifo";
    	const char* tubeCoreToPilote = "coreToPilote.fifo";
    	const char* tubeMeteo = "tubeMeteo.fifo";
     
    	char messagePilote[TAILLE_MESSAGE];
    	char messageMeteo[TAILLE_MESSAGE];
     
    	pipeFromPilote = open(tubePiloteToCore,O_RDONLY);
    	pipeFromMeteo = open(tubeMeteo,O_RDONLY);
    	pipeToPilote = open(tubeCoreToPilote,O_WRONLY);
     
    	read(pipeFromPilote,messagePilote,TAILLE_MESSAGE);
    		//printf("%s", messagePilote);
    	read(pipeFromMeteo,messageMeteo,TAILLE_MESSAGE);
    		//printf("%s", messageMeteo);
     
    	if(*messagePilote == 'y'){
    		write(pipeToPilote, messageMeteo,TAILLE_MESSAGE);
    		if(messagePilote == "ACK 0")
    			printf("%s",messagePilote);}
     
    	return EXIT_SUCCESS;
    }
    Je n'arrive pas à afficher le messagePilote dans la dernière condition de tour.c et je ne sais pas comment régler ce problème...
    Je ne sais déjà pas si ça vient de la condition en elle même, ou si le message n'est pas transmis sur le pipe depuis pilote.c .

    Il me reste plus que ça à faire ainsi qu'à lacer les close() et remove() et je suis bon, j'ai fini mon projet.
    Save me please !

  8. #8
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 800
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 800
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par mikamic Voir le message
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    	if(*messagePilote == 'y'){
    		write(pipeToPilote, messageMeteo,TAILLE_MESSAGE);
    		if(messagePilote == "ACK 0")
    			printf("%s",messagePilote);}
     
    	return EXIT_SUCCESS;
    }
    Mouais. Je pige pas trop ce que tu veux faire mais ici je détecte deux gros problèmes
    1. tu regardes si le premier caractère de la chaine "messagePilote" est "y". Et si c'est le cas, tu regardes si la chaine complète est "ACK_O". Ben à mon avis, si le premier caractère de cette chaine est "y", je vois mal comment la chaine peut alors être égale à "ACK_O" !!!
    2. apprends à comparer des chaines de façon correcte !!! On ne compare pas deux chaines avec "==" !!!
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  9. #9
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2016
    Messages : 5
    Par défaut
    1. En fait, ce que je cherche à faire, c'est :
    1)envoyer un message de pilote à tour
    2)à la réception de ce message, en envoyer un de tour à pilote
    3)à la réception de ce dernier, envoyer un accusé de réception et l'afficher
    Mon if est complètement bancal, c'est juste le dernier essai de plusieurs tentatives...

    2.trouvé... strcmp.

    En fait, ce qu'il me faut, c'est simplement afficher le dernier message envoyé par pilote, pour être sûr qu'il est bien passé dans le pipe.

    -----

    Edit : Problème résolu, je pense.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    	if(*messagePilote == 'y')
    		write(pipeToPilote, messageMeteo,TAILLE_MESSAGE);
     
    	while(*messagePilote == 'y'){
    		read(pipeFromPilote,messagePilote,TAILLE_MESSAGE);
    		if(*messagePilote != 'y')
    			printf("%s",messagePilote);
    	}
    Edit 2 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    	if(*messagePilote == 'y')
    		write(pipeToPilote, messageMeteo,TAILLE_MESSAGE);
     
    	while(*messagePilote == 'y')
    		read(pipeFromPilote,messagePilote,TAILLE_MESSAGE);
    	printf("%s",messagePilote);

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

Discussions similaires

  1. comment faire communiquer deux PC
    Par a.fardon dans le forum Réseau
    Réponses: 5
    Dernier message: 13/01/2009, 19h02
  2. Comment faire communiquer deux threads
    Par mayu5 dans le forum POSIX
    Réponses: 3
    Dernier message: 14/05/2008, 13h45
  3. [SOAP] Comment faire communiquer deux applis?
    Par r0d dans le forum XML/XSL et SOAP
    Réponses: 7
    Dernier message: 29/04/2008, 14h45
  4. Réponses: 14
    Dernier message: 13/11/2007, 19h46
  5. comment faire communiquer deux form MDI?
    Par eponette dans le forum Langage
    Réponses: 3
    Dernier message: 17/08/2005, 12h20

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