2008-09-17 5 views
16

Comment utilisez-vous gen_udp dans Erlang pour faire de la multidiffusion? Je sais que c'est dans le code, il n'y a juste pas de documentation derrière. L'envoi de données est évident et simple. Je me demandais comment ajouter des adhésions. Non seulement ajouter des adhésions au démarrage, mais ajouter des adhésions en cours d'exécution serait également utile.Erlang Multicast

Répondre

14

Voici un exemple de code sur la façon d'écouter le trafic Bonjour/Zeroconf.

-module(zcclient). 

-export([open/2,start/0]). 
-export([stop/1,receiver/0]). 

open(Addr,Port) -> 
    {ok,S} = gen_udp:open(Port,[{reuseaddr,true}, {ip,Addr}, {multicast_ttl,4}, {multicast_loop,false}, binary]), 
    inet:setopts(S,[{add_membership,{Addr,{0,0,0,0}}}]), 
    S. 

close(S) -> gen_udp:close(S). 

start() -> 
    S=open({224,0,0,251},5353), 
    Pid=spawn(?MODULE,receiver,[]), 
    gen_udp:controlling_process(S,Pid), 
    {S,Pid}. 

stop({S,Pid}) -> 
    close(S), 
    Pid ! stop. 

receiver() -> 
    receive 
     {udp, _Socket, IP, InPortNo, Packet} -> 
      io:format("~n~nFrom: ~p~nPort: ~p~nData: ~p~n",[IP,InPortNo,inet_dns:decode(Packet)]), 
      receiver(); 
     stop -> true; 
     AnythingElse -> io:format("RECEIVED: ~p~n",[AnythingElse]), 
      receiver() 
    end. 
0

Multicast est spécifié par l'adresse IP

C'est la même en Erlang que pour toutes les langues. Les adresses IP 224.0.0.0 à 239.255.255.255 sont des adresses de multidiffusion.

Choisissez une adresse dans cette plage, vérifiez que vous ne chevauchez pas une adresse déjà affectée et que vous êtes prêt à partir.

http://www.iana.org/assignments/multicast-addresses

+0

Eh bien, je signifie accepter des données de multidiffusion. Ce n'est pas la question de l'envoi de données. –

10

Multicast envoi a été répondu, la réception nécessite un abonnement au groupe de multidiffusion.

Il semble (encore) non documenté, mais a déjà été couvert dans la liste de diffusion erlang-questions. http://www.erlang.org/pipermail/erlang-questions/2003-March/008071.html

{ok, Socket} = gen_udp:open(Port, [binary, {active, false}, 
             {reuseaddr, true},{ip, Addr}, 
             {add_membership, {Addr, LAddr}}]). 

où le Addr est le groupe de multidiffusion, et LAddr est une interface locale. (code gracieuseté de mog)

Les mêmes options utilisées ci-dessus peuvent être passées à inet:setopts, y compris {drop_membership, {Addr, LAddr}} pour arrêter d'écouter le groupe.

+0

merci pour les accessoires^_^ – mog

4

J'essaie de faire fonctionner cet exemple sur mon PC. Que pourrait-il arriver, si je reçois toujours le message {error, eaddrnotavail} en ouvrant la socket de réception?

Exemple 1: Cela fonctionne:

{ok, Socket} = gen_udp:open(?PORT, [{reuseaddr,true}, {ip,?SERVER_IP}, 
       {multicast_ttl,4}, {multicast_loop,false}, binary]), 

Exemple 2: Obtention d'une erreur d'exécution:

{ok, Socket} = gen_udp:open(?PORT, [{reuseaddr,true}, {ip,?MULTICAST_IP}, 
       {multicast_ttl,4}, {multicast_loop,false}, binary]), 

% -> {erreur, EADDRNOTAVAIL}

-define(SERVER_IP, {10,31,123,123}). % The IP of the current computer 
-define(PORT, 5353). 
-define(MULTICAST_IP, {224,0,0,251}). 
+0

J'ai ce problème sur Windows, mais exactement le même code fonctionne parfaitement sur Linux –