Delphi 2010 - Wininet耗尽手柄

时间:2011-08-03 21:14:56

标签: delphi winapi resources wininet aqtime

我有一个应用程序,它集中使用Wininet函数从Internet获取一些数据。我有时会得到一个非常奇怪的句柄相关错误消息:

Internal error in ConnectToHost when trying to create a session 
ERROR_INTERNET_OUT_OF_HANDLES: No more handles could be generated at this time. Wininet error code = 12001;

当发生这种情况时,我注意到我的应用程序创建了超过5000个句柄。我运行了一个资源配置文件,我发现wininet创建的一些句柄没有被释放。

所以,我创建了一个小应用程序来重现这个问题。代码很简单,除了分配一些wininet句柄然后释放它们之外什么都不做。那就是代码:

procedure request(const AUrl : AnsiString);
var
  sMethod     : AnsiString;
  pSession    : HINTERNET;
  pConnection : HINTERNET;
  pRequest    : HINTERNET;
  port        : Integer;
  flags       : DWord;
begin
  pSession := InternetOpen(nil, INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
  if Assigned(pSession) then
  try
    Port := INTERNET_DEFAULT_HTTP_PORT;
    pConnection := InternetConnectA(pSession, PAnsiChar(AUrl), port, nil, nil, INTERNET_SERVICE_HTTP, 0, 0);
    if Assigned(pConnection) then
      try
        sMethod := 'GET';
        flags := INTERNET_SERVICE_HTTP;
        pRequest := HTTPOpenRequestA(pConnection, PAnsiChar(sMethod), PAnsiChar(AUrl), nil, nil, nil, flags, 0);
        try
          if Assigned(pRequest) then
            ShowMessage('ok');
        finally
          InternetCloseHandle(pRequest);
        end;
      finally
        InternetCloseHandle(pConnection);
      end;
  finally
    InternetCloseHandle(pSession);
  end;
end;

在我的探查器上运行此示例,我得到了相同的句柄相关问题。

我认为InternetCloseHandle并没有释放句柄,因为我的资源配置文件告诉我,当我关闭应用程序时,我有3个实时句柄。那些是没有被释放的句柄:

pRequest
pConnection
pSession

有谁知道怎么摆脱这个?

修改

函数InternetCloseHandle工作正常,返回值为true

修改

我在互联网上搜索了很多,但我没有找到任何人抱怨这一点。但它正在发生。我想知道是否有人复制了这个问题,或者是否只是我。

2 个答案:

答案 0 :(得分:2)

原来是AQtime问题。我下载了另一个分析器,我也看了一下任务管理器,似乎正在释放句柄。但有时我仍然会遇到no more handles错误,我不明白为什么。但是我会打开另一个问题,因为这个只是为了看看为什么这些句柄没有被释放。

感谢我的帮助。

答案 1 :(得分:-1)

Http协议有一些限制,Wininet正在使用它们。 查看WinInet limits connections per server:

  

WinInet将与单个HTTP 1.0服务器的连接限制为四个同时连接。与单个HTTP 1.1服务器的连接仅限于两个同时连接。 HTTP 1.1规范(RFC2616)规定了双连接限制。 HTTP 1.0的四连接限制是一种自我限制,与许多流行的Web浏览器使用的标准一致。

也许您应该等到连接关闭后再尝试新连接