[erlang-questions] Multicast UDP sending question
Valentin Micic
v@REDACTED
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: erlang-questions@REDACTED [mailto:erlang-questions@REDACTED] 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
<jarrod@REDACTED>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,
> "jhr@REDACTED",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