Erlang Multicast

守給你的承諾、 提交于 2019-11-30 05:05:08

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. 

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.

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

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!