我正在使用Wininet在应用程序启动时执行与我的服务器的检查。
问题是,在调用CloseInternetHandle之后,socket状态仍然是在netstat上看到的CLOSE_WAIT,最糟糕的是它永远不会改变它的状态。
这是我正在使用的简单的代码。 我究竟做错了什么 ?
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); }
WinInet会尝试在可以重新使用套接字的地方重新使用套接字,所以即使释放了句柄,它也可以选择保持套接字处于活动状态,为下一次对InternetOpen的调用做好准备。 大多数时候这是一件好事,你不需要担心。
这不是手柄泄漏。 你可以看到这个,如果你把你的代码放在一个循环中,并查看netstat中的本地端口号:同一个套接字被重复使用一遍又一遍。 当你的进程完成后,套接字将被WinInet正确关闭。
如果您真的需要立即关闭它,可以通过在最终的InternetCloseHandle之后调用InternetSetOption来欺骗WinInet来完成此操作:
... InternetCloseHandle(hInternet); InternetSetOption(NULL, INTERNET_OPTION_SETTINGS_CHANGED, NULL, 0);
这样做会告诉WinInet全局WinInet设置已经改变了(例如在注册表中),所以它别无选择,只能关闭所有套接字并重置自身。 但是,这显然不是预期的用法,如果您与WinInet进行大量连接,将会对性能产生一定的影响。