[erlang-questions] eaddrinuse despite {reuseaddr, true}

Ahmed Omar <>
Thu Sep 5 13:56:35 CEST 2013


Hi JD,
I think you are maybe confusing reuseadrr or (SO_REUSEADDR) usage in
general.

AFAIK, In most sockets implementations, you can't bind two sockets with the
same exact source(port/IP)/protocol combination.
That's not specific to Erlang, but to most used operating systems.

Here's a good read on the topic (specially the table for possible
combination)
http://stackoverflow.com/questions/14388706/socket-options-so-reuseaddr-and-so-reuseport-how-do-they-differ-do-they-mean-t


A simple example to show one scenario of using reuseaddr:
%Listening on a specific IP and on a wildcard

> {ok, LSock1} = gen_tcp:listen(12345, [{reuseaddr,
true},{ip,{127,0,0,1}}]).
{ok,#Port<0.816>}
> {ok, LSock2} = gen_tcp:listen(12345, [{reuseaddr, true},{ip,{0,0,0,0}}]).

{ok,#Port<0.817>}
>

%Same without reuseaddr:

>
> f().
ok
> {ok, LSock1} = gen_tcp:listen(12346, [{ip,{127,0,0,1}}]).

{ok,#Port<0.818>}
> {ok, LSock2} = gen_tcp:listen(12346, [{ip,{0,0,0,0}}]).
** exception error: no match of right hand side value {error,eaddrinuse}

So in your case, sometimes it will succeed (if socket got actually closed
before the next gen_tcp:listen call, and in other times will fail because
the socket was not yet closed.

Does this answer your question?

Best Regards,
Ahmed Omar



On Thu, Sep 5, 2013 at 10:27 AM, JD Bothma <> wrote:

> On 5 September 2013 09:58, aman mangal <> wrote:
>
>>
>> The error is thrown in the first line. It is returning *{error, **
>> eaddrinuse}*  (where you are expeciting *{ok, LSock}*) because the port
>> is already being used by some different process. Two process cannot listen
>> on the same port at a time.
>>
>
>  It runs for a while, and sometimes gets through all bind/closes, but
> sometimes crashes mid-way.
>
> reuseaddr should be telling the OS that the closing socket may be reused
> when this process tries to listen on the same port again.
>
> No process was listening on this port before the test. This code should be
> ensuring that the OS allows listening on the socket even when the last
> close hasn't completely released the socket. Without reuseaddr, we can
> sometimes expect eaddrinuse because close returns before the socket is
> guaranteed to be completely released.
>
> That's if I haven't misunderstood something. If this code is correct,
> either something's happening on my machines that I'm not controlling
> properly or there's a synchronisation bug in the erlang networking code
> that I'd like to help identify and solve.
>
>
>> On Thu, Sep 5, 2013 at 1:16 PM, JD Bothma <> wrote:
>>
>>> Why can this sometimes exit with exception error: no match of right hand
>>> side value {error,eaddrinuse} ?
>>>
>>> As far as I know, nothing's connecting to the socket in this time.
>>>
>>> [ begin {ok, LSock} = gen_tcp:listen(12345, [{reuseaddr, true}]),
>>>            {error, timeout} = gen_tcp:accept(LSock, 0),
>>>            ok = gen_tcp:close(LSock)
>>>    end
>>>   || _X <- lists:seq(1, 100000) ].
>>>
>>> This is on R14 and 15 on linux and R16 on OS X.
>>>
>>> BTW it doesn't seem to happen if I don't accept. I'm debugging this
>>> behaviour in yaws with SSL but it also seems to happen with plain gen_tcp.
>>>
>>> JD
>>>
>>> _______________________________________________
>>> erlang-questions mailing list
>>> 
>>> http://erlang.org/mailman/listinfo/erlang-questions
>>>
>>>
>>
>
> _______________________________________________
> erlang-questions mailing list
> 
> http://erlang.org/mailman/listinfo/erlang-questions
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20130905/6e9d0033/attachment.html>


More information about the erlang-questions mailing list