Forum Linux.général Problème multicast et UDP

Posté par  .
Étiquettes : aucune
0
13
déc.
2006
Bonjour,

Je veut créer un logiciel en C (ou C++, peut m'importe) pouvant diffuser à plusieurs machines à la fois une information sur un réseau local. De plus, je veut qu'une machine émettant sur le réseau ne reçoive pas l'information qu'elle a diffusée.

Pour cela j'ai utilisé le multicast avec une socket UDP. Voici le code partiel de mon programme :

//Je crée ma socket UDP
struct sockaddr_in serv_addr;

sock = socket(AF_INET, SOCK_DGRAM, 0);
if(sock == -1) {printError("Erreur lors de la creation du socket"); return 1;}
int optReUseAddr = 1;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optReUseAddr, sizeof(int));

if (inet_aton("224.0.0.1", &serv_addr.sin_addr) < 0) {perror("inet_aton serv_addr"); return 1;}
serv_addr.sin_port = htons(port);
serv_addr.sin_family = AF_INET;

if (bind(sock, (struct sockaddr *) (&serv_addr), sizeof(serv_addr)) < 0)
{perror("CREATE CONN : erreur lors du bind "); return 1;}

/* ... */

//J'ajoute ma socket au groupe de multicast correspondant au réseau local ("224.0.0.1")
struct ip_mreq mreq;
int i=0;

if (inet_aton("224.0.0.1", &mreq.imr_multiaddr) < 0) {perror("inet_aton mreq"); return 1;}
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
{perror("setsockopt IP_ADD_MEMBERSHIP "); return 1;}

/* ... */

//Je désactive la réception par une machine de ses propres messages :
if (setsockopt(sock, SOL_IP, IP_MULTICAST_LOOP, &i, sizeof(int)) < 0)
{perror("setsockopt multicast "); return 1;}

/* ... */

//Initialisation terminée : j'envoi et je receoit les données (la reception se fait dans un thread différent)
nbrOctetEnv = sendto(sock, buff, strlen(buff), MSG_NOSIGNAL, (struct sockaddr *)(&serv_addr), sizeof(serv_addr));
nbrOctetRecv = recvfrom(param.sockComm, buff, 1024, MSG_NOSIGNAL, (struct sockaddr *)(&serv_addr), &i);

Tout cela compile et fonctionne correctement. Or je désire exécuter ce code sur une carte. Pas de problème là non plus : la compilation et l'initialisation de la socket se font correctement.
Cependant dans un premier temps la carte ne recevait ni ne multicastait de données sur le réseau. J'ai rajouté une route 'default' à la table de routage ce qui m'a permis de régler le problème de l'envoi mais pas de la réception. J'aurai donc plusieurs questions :

- Est-ce que le multicast est la solution la plus propre et la mieux adaptée pour diffuser de l'information à plusieurs machine à la fois ?
- Le multicast est-il plus proprope et / ou plus performant que le broadcast ?
- Si le broadcast est plus adapté, quelqu'un sait-il comment stopper la reception par une une machine de trames qu'elle a elle-même envoyée ? J'ai cherché des options pour le setsockopt mais je n'ai rien trouvé.
- Mon code est-il correct ? La configuration de ma socket est-elle complète ou manque-t-il des parties nécessaires pour un noyau seul mais gérées automatiquement par une distributon ?
- Mon problème ne viendrai-t-il pas du fait que mon PC (distrib Mandriva 2007) configure automatiquement quelque chose permettant la réception des trames, chose que ne doit pas faire le linux embarqué sur la carte (pas de distrib). Quelqu'un sait-il d'où cela peut venir ?
- J'ai remarqué que sur mon PC j'ai une adresse IPV6 assignée mon interface eth0 et pas sur ma carte. Est-il nécessaire que les deux machines gèrent IPV6 (j'en doute) ?

Merci d'avance pour vos réponse
  • # [Howto]

    Posté par  . Évalué à 3.

    A part te renvoyer sur le HOWTO http://tldp.org/HOWTO/Multicast-HOWTO-2.html , je ne sais pas...

    http://tldp.org/HOWTO/Multicast-HOWTO-3.html indique de mettre eventuellement une route pour les paquets multicast : "route add -net 224.0.0.0 netmask 240.0.0.0 dev eth0"

    Vérifie que ton kernel a bien le support multicast (quoique si ton programme tourne c'est sans doute le cas; jete un oeil dans /proc/net/dev_mcast s'il y a bien ton interface réseau de listée)

    Une fois que ton programme tourne, essaier de pinguer l'IP du groupe multicaste abonné (224.0.0.1) depuis une autre machine pour voir si quelqu'un répond

    Le HOWTO semble dire que 224.0.0.1 est plus ou moins reservée... essaie avec un autre groupe multicast ?..
    As-tu fait tourner un sniffeur de paquet (ethereal/wireshark) pour voir si des paquets étaient bien émis/reçus sur le réseau, à défaut d'être reçu par l'appli ?
    Es-tu bien en réseau "local", c'est-à-dire toutes tes machines sur le même lien ethernet (via un switch éventuellement), sans routeur entre les deux ? Le multicast nécessite que les routeurs soient adaptés...

    Sinon pour tes questions:
    - je pense qu'un multicast est effectivement plus propre; au moins, les programmes qui l'utilisent peuvent tourner en utilisateur normal; le broadcast a, je crois, l'inconvénient de devoir magouiller les paquet à la main et d'avoir les privilèges root
    - L'IPv6 n'a pas d'impact sur le multicast v4
    • [^] # Re: [Howto]

      Posté par  . Évalué à 2.

      Effectivement, le problème venait de mon addresse de multicast.
      J'ai utilisé 224.0.0.3 et tout marche parfaitement.
      J'avais lu sur un tutorial que l'adresse 224.0.0.1 désignait le réseau local. Le HOW à aussi l'air de dire que toute les machines pouvant répondre à un multicast sur 224.0.0.1 doivent le faire mais apparement cela ne marche pas tout à fait comme cela.

      En tout cas je te remercie pour ta réponse pertinente et rapide.

      PS : pour le mise en page et le double post, je suis désolé mais mon doigt a rippé sur la touche entrée.

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.