【问题标题】:Socket remains in CLOSE_WAIT state套接字保持在 CLOSE_WAIT 状态
【发布时间】:2014-10-02 17:55:21
【问题描述】:

当应用程序启动时,我正在使用 Wininet 对我的服务器进行检查。

问题是在调用 CloseInternetHandle 之后,套接字状态仍然是 CLOSE_WAIT,如 netstat 所示,最糟糕的是它永远不会改变它的状态。

这是我正在使用的简单代码。我做错了什么?

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);
    }

【问题讨论】:

  • 你要等多久才能宣布它“永不”改变?
  • 应用程序是否正在运行或调试器是否已暂停? CLOSE_WAIT 表示应用还没有关闭套接字。
  • 但是你可以看到我正在关闭它,它没有在调试器中运行。
  • 您没有关闭 TCP 连接。您正在关闭互联网句柄。 WinInet API 肯定支持 HTTP keep-alive 和连接池。暂停调试器会阻止清理。
  • @usr 正如我之前所说,它没有在调试器中运行,如何关闭 TCP 连接?

标签: c windows wininet


【解决方案1】:

WinInet 尝试尽可能地重用套接字,因此即使您释放句柄,它也可以选择保持套接字处于活动状态,为下一次调用 InternetOpen 做好准备。大多数情况下,这是一件好事,您无需担心。

这不是句柄泄漏。如果您将代码放入循环中并查看 netstat 中的本地端口号,您可以看到这一点:同一个套接字被一遍又一遍地重用。当您的进程完成时,WinInet 将正确关闭套接字。

如果您真的需要立即关闭它,您可以通过在最终的 InternetCloseHandle 之后调用 InternetSetOption 来欺骗 WinInet 执行此操作:

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

这样做会告诉 WinInet 全局 WinInet 设置已更改(例如在注册表中),因此它别无选择,只能关闭所有套接字并自行重置。但是,这显然不是预期的用途,如果您与 WinInet 建立大量连接,则会对性能产生一些影响。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-03
    • 2010-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多