On a POSIX system, if a network service crashes, by default there is a brief period of time (possibly a couple of minutes) before you can bind to the port that was being used again. This is a problem if your service restarts automatically after a crash, as it will then get an “Address already in use” error when it tries to bind to the port and your service will fail to start.
Whilst there are reasons for this default behaviour (slight risk that an existing client will continue talking to the restarted service without either side realizing that it’s a stale session), in general it isn’t what you want. If you have a secure protocol like TLS, that slight risk won’t be present anyway.
To fix this, the
SO_REUSEADDR socket option can be set with the
setsockopt command. That way, the restarted service will be able to bind to the port straight away without errors.
This would all be fine and dandy, but something that people often overlook in their zeal to fix the service restart problem, when they first run into it on POSIX systems, is that it’s not actually the right solution on a Windows system.
It turns out that on Windows, the behaviour that
SO_REUSEADDR achieves on POSIX is actually already present by default. However, if
SO_REUSEADDR is set on Windows, it behaves like
SO_REUSEPORT on POSIX, which means that more than one application can listen to the same port at once, which is rarely what you want, and will be positively unhelpful if you’re relying on getting a failure to detect whether a port is already being used or another process ends up stealing your port.
The solution that is right for most applications is to enable
SO_REUSEADDR only on POSIX systems, and for extra caution to enable
SO_EXCLUSIVEADDRUSE on Windows to prevent another process from binding to the port even it does have
/* Call immediately after creating socket "sockfd" */
int optval = 1;
if (-1 == setsockopt(
(const char*)&optval, sizeof optval))
/* Handle error */
You may have to do this configuration of the socket even if using a higher-level networking library like Boost ASIO rather than using the underlying sockets API directly, if the networking library doesn’t wrap it up for you.
This MSDN article explains more about the socket options on Windows.
This stackoverflow answer explains in detail about the various platform-specific issues.