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 :

Utilisation boite aux lettres [mq_open()]


Sujet :

C

  1. #1
    Nouveau candidat au Club
    Homme Profil pro
    Inscrit en
    Mai 2013
    Messages
    1
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mai 2013
    Messages : 1
    Par défaut Utilisation boite aux lettres [mq_open()]
    Bonjour,
    J'ai recherché sur divers sites une définition claire et précise du fonctionnement d'une boite aux lettres, de son intéret, etc. Parceque lire les man, ce n'est pas forcément suffisant...
    Je comprends la théorie du fonctionnement de chaque fonction, mais globalement, je n'y arrive pas.
    Quelqu'un pourrait il m'aider, ou bien s'il connait une page où tout cela est décrit facilement?
    Merci encore, et je m'excuse si quelque n'a pas été fait dans les règles de l'art

  2. #2
    Membre Expert
    Avatar de Metalman
    Homme Profil pro
    Enseignant-Chercheur
    Inscrit en
    Juin 2005
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Enseignant-Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 049
    Par défaut
    Alors, sans être expert, je crois qu'il s'agit d'un mécanisme d'IPC.

    Chez IBM ils ont un produit assez connu : MQ Series qui sert justement à envoyer des messages entre diverses applications (elles même sur diverses machines).
    D'après ce lien, cela a l'air confirmé.

    Pour être plus précis : tu vas envoyer et recevoir des messages de façon asynchrone.
    Plusieurs applications vont pouvoir ouvrir une même file (identifiée par son nom), puis émettre/recevoir des messages dedans.
    L'intérêt de cette IPC, c'est juste d'envoyer des messages de façon asynchrone, avec un nom "commun" de file.
    Par de fork nécessaire dans ton application pour créer de l'intercommunication, pas besoin de connaitre un chemin dans ton arborescence... juste le nom de la file.

    Après : je n'ai pas testé ce mécanisme. Je ne peux que te dire les souvenirs que j'ai de MQ Series, et ce que je déduis de quelques lignes du man !
    --
    Metalman !

    Attendez 5 mins après mes posts... les EDIT vont vite avec moi...
    Les flags de la vie : gcc -W -Wall -Werror -ansi -pedantic mes_sources.c
    gcc -Wall -Wextra -Werror -std=c99 -pedantic mes_sources.c
    (ANSI retire quelques fonctions comme strdup...)
    L'outil de la vie : valgrind --show-reachable=yes --leak-check=full ./mon_programme
    Et s'assurer que la logique est bonne "aussi" !

    Ma page Developpez.net

  3. #3
    Membre Expert
    Avatar de Metalman
    Homme Profil pro
    Enseignant-Chercheur
    Inscrit en
    Juin 2005
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Enseignant-Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 049
    Par défaut
    Comme je n'avais jamais travaillé sur les MQ, j'ai voulu tester en vitesse.

    ansi.h
    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
    #ifndef ANSI_H_
    # define ANSI_H_
     
    # include <unistd.h>
    # include <stdlib.h>
    # include <stdio.h>
    # include <stdarg.h>
    # include <string.h>
    # include <errno.h>
     
    # define MAXLINE	4096
     
    char	*strdup(const char	*str);
     
    #endif /* !ANSI_H_ */
    ansi.c
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #include "ansi.h"
     
    char	*strdup(const char	*str)
    {
      size_t	len;
      char		*copy;
     
      len = strlen(str) + 1;
      if ((copy = malloc(len * sizeof (char))) == NULL)
        return (NULL);
      memcpy(copy, str, len);
      return (copy);
    }
    (normalement j'ai beaucoup beaucoup + de fonctions dedans...)

    main.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #ifndef MAIN_H_
    # define MAIN_H_
     
    # include <unistd.h>
    # include <stdlib.h>
    # include <stdio.h>
    # include <fcntl.h>		/* For O_* constants */
    # include <sys/stat.h>	/* For mode constants */
    # include <mqueue.h>
    # include <string.h>
     
    # include "ansi.h"
     
    #endif /* !MAIN_H_ */
    main.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
    #include "main.h"
     
    #define MQ_NAME "/queuetest"
    #define BUF_LEN 512
     
    int	main(void)
    {
    	ssize_t	len_recv;
    	mqd_t	My_MQ;
    	char	*text;
    	char	recv[BUF_LEN];
    	int		ret;
     
    	My_MQ = mq_open(MQ_NAME, O_RDWR);
    	if (My_MQ == -1)
    	{
    		perror("Error : mq_open failed !\n");
    		return (-1);
    	}
     
    	printf("%s\n", "Envoi msg de priorite 42");
    	text = strdup("Message test prio : 42 !");
    	ret = mq_send(My_MQ, text, strlen(text), 42);
    	free(text);
     
    	printf("%s\n", "Envoi msg de priorite 21");
    	text = strdup("Message test prio : 21 !");
    	ret = mq_send(My_MQ, text, strlen(text), 21);
    	free(text);
     
    	memset(recv, 0, BUF_LEN);
    	len_recv = mq_receive(My_MQ, recv, BUF_LEN, NULL);
    	printf("Premier msg recu (len : %u) : %s\n", (unsigned int) len_recv, recv);
     
    	memset(recv, 0, BUF_LEN);
    	len_recv = mq_receive(My_MQ, recv, BUF_LEN, NULL);
    	printf("Deuxieme msg recu (len : %u) : %s\n", (unsigned int) len_recv, recv);
     
    	mq_close(My_MQ);
    	return (0);
    }
    Compilé avec : gcc -W -Wall -Werror -ansi -pedantic -lrt ansi.c main.c

    Quand j'exécute ça ne fonctionne pas, cela m'affiche "Function not implemented".
    D'après ce lien, un sleep(1) règle le problème ?!?
    Je n'ai pas encore essayé (conditions de dév pas géniale là tout de suite...).
    Mais contrairement à ce que le monsieur raconte sur le lien, il ne faut PAS mettre plusieurs '/' dans le nom de la queue ! Seulement 1 au début.
    Enfin, toujours d'après le 1er lien en haut.

    J'édite dès que j'ai un truc qui marche, et je le mets ici...
    Le MQ m'intéresse grandement !
    --
    Metalman !

    Attendez 5 mins après mes posts... les EDIT vont vite avec moi...
    Les flags de la vie : gcc -W -Wall -Werror -ansi -pedantic mes_sources.c
    gcc -Wall -Wextra -Werror -std=c99 -pedantic mes_sources.c
    (ANSI retire quelques fonctions comme strdup...)
    L'outil de la vie : valgrind --show-reachable=yes --leak-check=full ./mon_programme
    Et s'assurer que la logique est bonne "aussi" !

    Ma page Developpez.net

  4. #4
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 391
    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 391
    Par défaut
    "not implemented" c'est parce qu'il existe deux types de files de message sous *n*x, et qu'ils ne sont pas toujours implémentés tous les deux:
    • mq_open(), pour les IPC POSIX.
    • msgget(), pour les IPC System V. Ces messages possèdent un paramètre supplémentaire pouvant être utilisé comme filtre, bien utile dans certains cas.
    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.

  5. #5
    Membre Expert
    Avatar de Metalman
    Homme Profil pro
    Enseignant-Chercheur
    Inscrit en
    Juin 2005
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Enseignant-Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 049
    Par défaut
    Ca j'ai fini par le voir.
    La page OpenGroup de l'interface POSIX : lien

    Ce qui m'étonne, c'est que les interfaces sont déclarées, quelques docs perdues en parlent : Linuxpedia
    Mais.... nul part ça fonctionne !

    Apparemment les mq_* sont inclus dans les kernels linux 2.6 et +.
    Ce qui "normalement" est dispo sur quasiment tous les linux du moment et depuis 5 ans.... mais en fait non ?
    --
    Metalman !

    Attendez 5 mins après mes posts... les EDIT vont vite avec moi...
    Les flags de la vie : gcc -W -Wall -Werror -ansi -pedantic mes_sources.c
    gcc -Wall -Wextra -Werror -std=c99 -pedantic mes_sources.c
    (ANSI retire quelques fonctions comme strdup...)
    L'outil de la vie : valgrind --show-reachable=yes --leak-check=full ./mon_programme
    Et s'assurer que la logique est bonne "aussi" !

    Ma page Developpez.net

  6. #6
    Membre Expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Par défaut
    En fait ça dépend de la configuration du noyau, tu peux ou non y inclure la gestion des IPC à la POSIX.
    Suivant la distrib, le fichier décrivant les options utilisées se trouve dans /boot ou /usr/src/linux/ ou ailleurs.
    Par exemple j'ai un opensuse, le fichier de config se trouve dans /boot et contient :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    CONFIG_SYSVIPC=y
    CONFIG_SYSVIPC_SYSCTL=y
    CONFIG_POSIX_MQUEUE=y
    CONFIG_POSIX_MQUEUE_SYSCTL=y
    Je peux donc utiliser les deux façons de faire et c'est effectivement le cas.

  7. #7
    Membre Expert
    Avatar de Metalman
    Homme Profil pro
    Enseignant-Chercheur
    Inscrit en
    Juin 2005
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Enseignant-Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 049
    Par défaut
    Je pense avoir trouvé mon problème, sur une FreeBSD 7 ça a fonctionné nickel (après les 2-3 manip' pour activer les POSIX MQ)... et en fouinant sur le net, j'ai eu ma réponse par pur hasard : je testais sur des machines OVH sous Debian.... et même si le noyau est supérieur au 2.6, les POSIX MQ ne sont pas nécessairement disponibles !

    Du coup, je ressors un Linux ailleurs pour tester...
    Je posterai les sources et ce qu'il faut activer dès que j'ai tout rassemblé.
    --
    Metalman !

    Attendez 5 mins après mes posts... les EDIT vont vite avec moi...
    Les flags de la vie : gcc -W -Wall -Werror -ansi -pedantic mes_sources.c
    gcc -Wall -Wextra -Werror -std=c99 -pedantic mes_sources.c
    (ANSI retire quelques fonctions comme strdup...)
    L'outil de la vie : valgrind --show-reachable=yes --leak-check=full ./mon_programme
    Et s'assurer que la logique est bonne "aussi" !

    Ma page Developpez.net

  8. #8
    Membre Expert
    Avatar de Metalman
    Homme Profil pro
    Enseignant-Chercheur
    Inscrit en
    Juin 2005
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Enseignant-Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 049
    Par défaut
    Ca fonctionne en effet parfaitement sur une Debian 6 (Squeeze).
    Je vais juste expliquer en vitesse comment installer sur FreeBSD (version 7 minimum), et compiler sur les *n*x.

    Voici le code "final" déjà :

    ansi.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #ifndef ANSI_H_
    # define ANSI_H_
     
    # include <unistd.h>
    # include <stdlib.h>
    # include <string.h>
     
    char	*strdup(const char	*str);
     
    #endif /* !ANSI_H_ */
    ansi.c
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #include "ansi.h"
     
    char	*strdup(const char	*str)
    {
      size_t	len;
      char		*copy;
     
      len = strlen(str) + 1;
      if ((copy = malloc(len * sizeof (char))) == NULL)
        return (NULL);
      memcpy(copy, str, len);
      return (copy);
    }
    main.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #ifndef MAIN_H_
    # define MAIN_H_
     
    # include <unistd.h>
    # include <stdlib.h>
    # include <stdio.h>
    # include <fcntl.h>	/* For O_* constants */
    # include <sys/stat.h>	/* For mode constants */
    # include <mqueue.h>
    # include <string.h>
     
    # include "ansi.h"
     
    #endif /* !MAIN_H_ */
    main.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
    44
    45
    46
    47
    #include "main.h"
     
    #define MQ_NAME "/queuetest"
    #define BUF_LEN 512
     
    int			main(void)
    {
      struct mq_attr	attr;
      ssize_t		len_recv;
      mqd_t			My_MQ;
      char			*text;
      char			recv[BUF_LEN];
      int			ret;
     
      attr.mq_flags = 0;
      attr.mq_maxmsg = 10;
      attr.mq_msgsize = BUF_LEN;
      attr.mq_curmsgs = 0;
     
      My_MQ = mq_open(MQ_NAME, O_RDWR | O_CREAT, 0644, &attr);
      if ((int) My_MQ == -1)
      {
        perror("Error : mq_open failed !\n");
        return (-1);
      }
     
      printf("%s\n", "Envoi msg de priorite 42");
      text = strdup("Message test prio : 42 !");
      ret = mq_send(My_MQ, text, strlen(text), 42);
      free(text);
     
      printf("%s\n", "Envoi msg de priorite 21");
      text = strdup("Message test prio : 21 !");
      ret = mq_send(My_MQ, text, strlen(text), 21);
      free(text);
     
      memset(recv, 0, BUF_LEN);
      len_recv = mq_receive(My_MQ, recv, BUF_LEN, NULL);
      printf("Premier msg recu (len : %u) : %s\n", (unsigned int) len_recv, recv);
     
      memset(recv, 0, BUF_LEN);
      len_recv = mq_receive(My_MQ, recv, BUF_LEN, NULL);
      printf("Deuxieme msg recu (len : %u) : %s\n", (unsigned int) len_recv, recv);
     
      mq_close(My_MQ);
      return (0);
    }
    Sur FreeBSD 7.0 (première version de FreeBSD à supporter les POSIX message queues), mon retour d'expérience :
    Première erreur dès le lancement : "Bad system call".
    Une petite recherche, et il suffisait de taper en root : "kldload mqueuefs".
    Puis monter le queuefs en root (ne pas oublier de créer le /mnt/queue avant, ou ailleurs) : mount -t mqueuefs null /mnt/mqueue
    L'option kernel (pour recompiler) est : options P1003_1B_MQUEUE
    Pour plus de détails pour l'ajout du module kernel (en live + option recompilation kernel) : manuel freebsd de mqueuefs

    Sur Debian 6 (Squeeze), par défaut l'option est activée.
    L'option kernel est : CONFIG_POSIX_MQUEUE
    Le code fonctionne parfaitement de base.

    Par contre, chez OVH avec des Debian, cela ne fonctionne pas toujours !
    Sur un RPS (paix à leurs âmes d'ici quelques mois !), et un VPS (avant 2013), cela ne fonctionne pas.
    Mais sur un VPS 2013 "Classic 2" oui.
    Caractéristique du RPS :
    Linux r*****.ovh.net 2.6.32.2-xxxx-std-ipv6-64 #4 SMP Sat Sep 18 12:09:32 UTC 2010 x86_64 GNU/Linux
    Caractéristique du VPS (avant 2013) :
    Linux vps*****.ovh.net 3.2.13-grsec-xxxx-grs-ipv6-64-vps #1 SMP Thu Mar 29 11:32:09 UTC 2012 x86_64 GNU/Linux
    Caractéristique du VPS 2013 "Classic 2" :
    Linux vps***** 2.6.32-042stab076.8 #1 SMP Tue May 14 20:38:14 MSK 2013 x86_64 GNU/Linux
    Je ne sais pas trop d'où vient le problème... IPv6 ?... GRSec ?....
    Bref... j'ai essayé de monter le queuefs sur les 2 machines OVH, aucune ne connaissait de type "queue" ou "queuefs".
    --
    Metalman !

    Attendez 5 mins après mes posts... les EDIT vont vite avec moi...
    Les flags de la vie : gcc -W -Wall -Werror -ansi -pedantic mes_sources.c
    gcc -Wall -Wextra -Werror -std=c99 -pedantic mes_sources.c
    (ANSI retire quelques fonctions comme strdup...)
    L'outil de la vie : valgrind --show-reachable=yes --leak-check=full ./mon_programme
    Et s'assurer que la logique est bonne "aussi" !

    Ma page Developpez.net

Discussions similaires

  1. Réponses: 0
    Dernier message: 21/10/2014, 10h39
  2. récupération mail boite aux lettres
    Par Gary_Stoupy dans le forum Access
    Réponses: 11
    Dernier message: 22/01/2007, 12h15
  3. Boites aux lettres de MS Exchange 5.5
    Par Safaritn dans le forum Exchange Server
    Réponses: 1
    Dernier message: 03/01/2007, 11h19
  4. Outlook 2003 plusieurs boite aux lettres
    Par Destiny dans le forum Outlook
    Réponses: 4
    Dernier message: 31/10/2006, 21h31
  5. Outlook 2003 plusieurs boite aux lettre
    Par Destiny dans le forum Outlook
    Réponses: 1
    Dernier message: 26/10/2006, 17h49

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