Sargun Dhillon
Sargun Dhillon

Reputation: 1848

How to multicast using gen_udp in Erlang?

How do you use gen_udp in Erlang to do multicasting? I know its in the code, there is just no documentation behind it. Sending out data is obvious and simple. I was wondering on how to add memberships. Not only adding memberships at start-up, but adding memberships while running would be useful too.

Upvotes: 18

Views: 5836

Answers (4)

Bwooce
Bwooce

Reputation: 2143

Multicast sending has been answered, receipt requires subscription to the multicast group.

It (still) seems undocumented, but has been covered on the erlang-questions mailing list before. 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}}]).

where the Addr is the multicast group, and LAddr is a local interface. (code courtesy of mog)

The same options used above can be passed to inet:setopts including {drop_membership, {Addr, LAddr}} to stop listening to the group.

Upvotes: 11

Matthias
Matthias

Reputation: 61

I try to get this example running on my PC. What could happen, if I get always the message {error,eaddrnotavail} by opening the receive socket?

Example 1: This works:

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

Example 2: Getting an runtime Error:

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

% --> {error,eaddrnotavail}

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

Upvotes: 4

user177800
user177800

Reputation:

Here is example code on how to listen in on Bonjour / Zeroconf traffic.

-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. 

Upvotes: 15

Mark Harrison
Mark Harrison

Reputation: 304662

Multicast is specified by IP Address

It's the same in erlang as for all languages. The IP addresses 224.0.0.0 through 239.255.255.255 are multicast addresses.

Pick an address in that range, check that you're not overlapping an already assigned address, and you are good to go.

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

Upvotes: 0

Related Questions