[erlang-questions] Multicast UDP sending question

Valentin Micic v@REDACTED
Fri Nov 20 16:22:27 CET 2009


Don't know what to tell you -- I've tried similar thing from Windoze and got
what I've expected:

Started two shells with following result:

FIRST:

Erlang (BEAM) emulator version 5.5.4 [async-threads:0]

Eshell V5.5.4  (abort with ^G)
(vhlr@REDACTED)1> gen_udp:open( 9999, [{reuseaddr, true}] ).
{ok,#Port<0.97>}
(vhlr@REDACTED)2>

SECOND:

Erlang (BEAM) emulator version 5.5.4 [async-threads:0]

Eshell V5.5.4  (abort with ^G)
(uscript@REDACTED)1> gen_udp:open( 9999, [{reuseaddr, true}] ).
{error,eaddrinuse}
(uscript@REDACTED)2>


Hope this is helpful too.

V/
-----Original Message-----
From: Sam Bobroff [mailto:samb@REDACTED] 
Sent: 20 November 2009 04:07 PM
To: Jarrod Roberson
Cc: Valentin Micic; Torben Hoffmann; Erlang
Subject: Re: [erlang-questions] Multicast UDP sending question

Hello,

Jarrod Roberson wrote:
> On Tue, Nov 17, 2009 at 9:15 AM, Valentin Micic
<v@REDACTED>wrote:
>
>   
>> 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.
>>
>>     
>
> thanks for the clarification. I am not sure how the Erlang internals work.
> Can you explain what {reuseaddr,true} does then, if not bind the same UDP
> port to multiple sockets.
> There are LOTS of applications on a OSX that all bind to 224.0.0.251:5353,
> is there a semantic different I am missing.
> Thanks for taking the time to explain this

I was pretty sure that Linux's reuseaddr option *did* allow the same UDP 
port to be bound to more than one socket, so I thought I'd test it. It's 
easy to do with Erlang:

I used the following test code on Ubuntu Linux 2.6.31:

-module(udp).
-export([start/0]).

start() ->
        {ok, Port} = gen_udp:open(9999, [{reuseaddr, true}]),
        io:fwrite("Bound to port: ~p\n", [Port]),
        loop().

loop() ->
        receive
                Msg -> io:fwrite("Msg: ~p\n", [Msg])
        end,
        loop().

Running this in one console and then using "netcat -u localhost 9999" in 
another and hitting enter a few times gives the following output:

 $ erl +B -noshell -run udp
Bound to port: #Port<0.289>
Msg: {udp,#Port<0.289>,{127,0,0,1},49272,"\n"}
Msg: {udp,#Port<0.289>,{127,0,0,1},49272,"\n"}
Msg: {udp,#Port<0.289>,{127,0,0,1},49272,"\n"}

Leaving this running and running another copy of it in another shell 
produces:

$ erl +B -noshell -run udp
Bound to port: #Port<0.289>

The bind has succeeded and so the same UDP port is now bound by both 
processes (with different sockets). Now hitting enter into the netcat 
terminal produces this in the second window:

Msg: {udp,#Port<0.289>,{127,0,0,1},54312,"\n"}
Msg: {udp,#Port<0.289>,{127,0,0,1},54312,"\n"}

No output is produced in the first window -- under Linux the second 
binding of the port seems to get the traffic. But if you close the 
second erl then the traffic will return to the first process.

I hope this was useful :-)

Sam.



More information about the erlang-questions mailing list