[erlang-questions] Multicast UDP sending question

Valentin Micic <>
Tue Nov 17 15:15:14 CET 2009


You cannot open the same UDP port twice (or, shall I say -- bound the same
UDP port to two different sockets). The story about N, N+1 port as well as
explanation indicated that this is an Erlang restriction due to the socket
library used is - well... pure fiction. 

I haven't dealt with multicast recently, but as far as I remember you do not
have to do anything special to be able to send to a multicast address -- any
standard UDP socket would do; you just need to reference the multicast
address as a destination IP address in sendto call. 
OTOH, if you want to receive multicast traffic you would have to add
membership -- this causes local MAC layer to assume additional link address,
so it can receive such a packet from the wire (*)

V/

(*) If you sending a packet from the same UDP socket that holds membership
to a multicast group to which you're sending to, such packet should be
received by a sending socket as well.

-----Original Message-----
From:  [mailto:] On
Behalf Of Torben Hoffmann
Sent: 17 November 2009 03:22 PM
To: Jarrod Roberson
Cc: Erlang
Subject: Re: [erlang-questions] Multicast UDP sending question

Hi Jarrod,

I have found some old code where we set-up UDP multicast - I cannot remember
the details, but it is not quite like the approach you are using:

Transmit

gen_udp:open(?PORT_NUM_TX_MULTI,
                                       [binary, {active, true},
                                        {ip, GwIP},
                                        inet, {multicast_ttl, 255},
                                        {multicast_loop, false},
                                        {multicast_if, GwIP}]),

Receive:

gen_udp:open(?PORT_NUM_RX_MULTI,
                                       [binary, {active, true},
                                        {multicast_if, GwIP},
                                        inet,{multicast_ttl, 255},
                                        {multicast_loop, false},
                                        {add_membership,
{MultiAddr,GwIP}}]),

The two ports PORT_NUM_TX_MULTI and PORT_NUM_RX_MULTI should be N and N+1
where N is your desired port number - as far as I understand UDP/TCP for
Erlang the ports always comes in pairs due to some things with the C socket
library used, but do check up on this by yourself or just try out the stuff
above and see if it works ;-)

Cheers,
Torben


On Tue, Nov 17, 2009 at 03:35, Jarrod Roberson
<>wrote:

> I have gotten a good start on my program, my first REAL Erlang program.
> I have it listening for messages, reading them and parsing them. I also
> have
> it sending them.
> The one little thing that is bothering me is I can't SEND on Port 5353, I
> have tried everything.
> All the other applications on my machine and listen AND send on port 5353,
> SubEthaEdit, iTunes, iChat.
> The all report Port: 5353 when sending multicast messages.
> I really want my application to play nice and do the same thing, send on
> Port 5353.
> Here is my module as it stands now.
>
> -module(zeroconf).
>
> -include("zeroconf.hrl").
>
> -export([open/0,start/0]).
> -export([stop/1,receiver/0]).
> -export([send/1]).
>
> -define(ADDR, {224,0,0,251}).
> -define(PORT, 5353).
>
> send(Domain) ->
>    {ok,S} = gen_udp:open(0,[{broadcast,true}]), % I really want this Port
> to be 5353 :-(
>    %{ok,S} = gen_udp:open(?PORT,[{reuseaddr,true}, {ip,?ADDR},
> {broadcast,true}, {multicast_ttl,4}, {multicast_loop,false}, binary]), %
> this doesn't complain or throw errors but it also doesn't work :-(
>    P =
>
>
#dns_rec{header=#dns_header{},qdlist=[#dns_query{domain=Domain,type=ptr,clas
s=in}]},
>    gen_udp:send(S,?ADDR,?PORT,inet_dns:encode(P)),
>    gen_udp:close(S).
>
> open() ->
>   {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(),
>   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.
>
> Here is what some output looks like.
>
> This is a QUERY from SubEthaEdit looking for other instances on the local
> network, notice that it says Port: 5353
> From: {192,168,0,105}
> Port: 5353
> Data:
> {ok,{dns_rec,{dns_header,0,true,'query',true,false,false,false,false,0},
>                   [],
>                   [{dns_rr,"_see._tcp.local",ptr,in,0,0,
>                            "",undefined,[],
>                            false}],
>                   [],[]}}
>
> Now here is a QUERY from my module looking for instances of iTunes on the
> local network, notice it says Port: 59795
> With the code the way it is now, that port is random. I really want it to
> be
> 5353.
>
> From: {192,168,0,105}
> Port: 59795
> Data:
> {ok,{dns_rec,{dns_header,0,false,'query',false,false,false,false,false,
>                               0},
>                   [{dns_query,"_daap._tcp.local",ptr,in}],
>                   [],[],[]}}
>
> Does anyone have any arcane insight in to UDP multicast at all?
>
>
> --
> Jarrod Roberson
> 678.551.2852
>



-- 
http://www.linkedin.com/in/torbenhoffmann



More information about the erlang-questions mailing list