eaddrinuse
Serge Aleynikov
serge@REDACTED
Thu Apr 28 15:37:56 CEST 2005
Brian Buchanan wrote:
> On Thu, 28 Apr 2005, Dietmar Schaefer wrote:
>>If I understand it right
>>
>> {reuseaddr, Boolean} as parameter for gen_tcp:listen allows local
>>reuse of port numbers.
>>
>>
>>So the error eaddrinuse should not occur ?
>>
>>
>>Every time I try to reconnect to the server I get this error.
>
> reuseaddr (or SO_REUSEADDR as it is translated to the kernel) only allows
> reuse of port numbers that were recently used but not currently in use.
> (They are not normally available for some period of time in order to
> provide a strict implementation of the TCP specification). If another
> open socket has that port number, you won't be able to bind it.
It looks like when you restart the server, the listener's Pid doesn't
get terminated, and it's still holding the socket open.
Most common use of {reuseaddr, true} option is to handle reacquisition
of a socket by a server in the following scenario:
1. A listening server is started.
2. It receives a connection request, and spawns a child process to
handle it.
3. The listening server terminates without killing the child, who's
still processing the request on the established connection.
4. The listening server gets restarted.
However, if you are trying to start the second instance of a TCP server
and attempt to bind to the same IP:Port, it will fail even though
{reuseaddr, true} is specified.
> I know that at least BSD-derived OSes support a SO_REUSEPORT option for
> setsockopt() that enables multiple sockets to simultaneously listen on the
> same address and port if all of them enable the option. The Erlang inet
> module doesn't appear to support this flag, however.
I believe the duplicate bindings (i.e. to the same IP address and port)
are *only* possible for UDP multicast binds. TCP doesn't support this
and should always fail with eaddrinuse if another process is active and
is bound to that socket. UDP non-multicast binds with {reuseaddr, true}
will allow you to "steal" a socket from another process (without that
process knowing about it), yet the kernel will only deliver UDP messages
to the latest process that bound the UDP socket.
It is possible, however, to do a TCP bind to the same port if you use
{reuseaddr, true}, and a *different* local IP address.
Serge
More information about the erlang-questions
mailing list