Ok, the title might be a slightly rhetorical question:
I’m writing an application in C++ using VStudio.NET and Windows XP. The application asserts an error, I choose to examine it under a debugger, I fix the error, stop the application, and restart it. Upon restarting the application, it throws a different assertion — the socket cannot be bound, because it is already in use.
Kill the new incarnation, check the process table. No sign of the previous app. netstat.exe -a shows the port still bound.
Kill the debugger/dev environment, in case it has some of the resources still locked in limbo. netstat.exe -a shows the port still bound.
Log out and log back in. netstat.exe -a shows the port no longer bound.
What the fuck? All resources in use by a program should be released by the kernel when the process ends, even if it was under debugging when it ends. And where are these traces of the application hanging around that a session restart fixes it?
This happens on UNIX too, see http://hea-www.harvard.edu/~fine/Tech/addrinuse.html.
Not the same thing –
a TIME_WAIT state isn’t on a listen socket, it’s on an actual TCP connection. Basically, the socket API says that by default, you can’t bind() to a local port to listen if there is an existing connection (not other listen socket) using the same port for the local part of the connection. If you set SO_REUSEADDR on the new listen socket before you bind, it will override this default.
The problem I’m running into is that the windows TCP stack is not closing the listen socket itself when the program terminates abnormally under debugging. I can see if maybe this is some variation on the TIME_WAIT state — if there’s an existing TCP connection stuck in that state trying to clear — but since all of my connections are over localhost I highly doubt it.
Use netstat -ao to find out what the PID of the process keeping it open.