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?
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_WAITstate 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 thesockaddrstruct filled with your local address and a random port.UPDATE: As using a specific local port is a requirement, consider setting
SO_LINGERwithl_onoff=1andl_linger=0so 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_WAITdelay by changing the value of this registry key (highly discouraged!):