Search code examples
cwindowswininet

Socket remains in CLOSE_WAIT state


I am using Wininet to perform a check with my server when the application get started.

The problem is that after calling CloseInternetHandle the socket state remains CLOSE_WAIT as seen on netstat, and the worst part is that it never changes it state.

Here is the simple code I am using. What am I doing wrong ?

hInternet = InternetOpen(NULL, INTERNETOPENTYPEPRECONFIG, NULL, NULL, 0);
    if (hInternet)
    {
        hFile = InternetOpenUrl(hInternet, url, NULL, 0, INTERNETFLAGRELOAD, 0);

        InternetReadFile(hFile, &buffer, 20, &btsRead);
        InternetCloseHandle(hFile);
        InternetCloseHandle(hInternet);
    }

Solution

  • WinInet tries to re-use sockets where it can, so even when you release the handle it can choose to keep the socket active, ready for the next call to InternetOpen. Most of the time this is a good thing and you don't need to worry about it.

    It is not a handle leak. You can see this if you put your code in a loop and look at the local port number in netstat: the same socket is getting reused over and over again. When your process finishes, the socket will be closed properly by WinInet.

    If you really need it to be closed immediately, you can fool WinInet into doing this by calling InternetSetOption after your final InternetCloseHandle:

    ...
    InternetCloseHandle(hInternet);
    InternetSetOption(NULL, INTERNET_OPTION_SETTINGS_CHANGED, NULL, 0);
    

    Doing this tells WinInet that global WinInet settings have changed (e.g. in the Registry) so it has no choice but to close all sockets and reset itself. However this obviously is not the intended usage and will have some performance impact if you are making lots of connections with WinInet.