I'm binding a client TCP socket to a specific local port. To handle the situation where the socket remains in TIME_WAIT
state for some time, I use setsockopt()
with SO_REUSEADDR
on a socket.
It works on Linux, but does not work on Windows, I get WSAEADDRINUSE
on connect()
call when the previous connection is still in TIME_WAIT
.
MSDN is not exactly clear what should happen with client sockets:
[…] For server applications that need to bind multiple sockets to the same port number, consider using
setsockopt
(SO_REUSEADDR
). Client applications usually need not call bind at all—connect chooses an unused port automatically. […]
How do I avoid this?
Best Answer
When you create a socket with
socket()
, it has only a type and a protocol family. The ideal is tobind()
it to a local address:port too.The error you mentioned normally happens when the last connection to the same host:port didn't have a graceful shutdown (FIN/ACK FIN/ACK). In these cases, the socket stays in
TIME_WAIT
state for a certain period of time (OS dependent, but adjustable).What happens then is when you try to
connect()
to the same host and same port, it uses the default socket's name/address/port/etc, but this combination is already in use by your zombie socket. To avoid this, you can change the local address:port used to establish the connection by callingbind()
after the socket creation, providing thesockaddr
struct filled with your local address and a random port.UPDATE: As using a specific local port is a requirement, consider setting
SO_LINGER
withl_onoff=1
andl_linger=0
so your socket won't block uponclose
/closesocket
, it will just ignore queued data and (hopefully) close the fd. As a last resort you can adjust theTIME_WAIT
delay by changing the value of this registry key (highly discouraged!):