Delphi、Android、SSL - IdSMTP ConnectTimeout - 在预设超时后不会终止与服务器的连接

Delphi, Android, SSL - IdSMTP ConnectTimeout - after preset timeout does not terminate connection to the server

当我将 ConnectTimeout 设置为 IdSMTP(例如 30 秒)并且 SMTP 服务器不可用时,它从 SMTP 服务器起飞大约 105 秒。

这是版本 10 中的 Indy 组件 - *250.bpl,OpenSSL v1.0.2。

使用 IdFTP ConnectTimeout 工作没有任何问题。

哪里可能有错误?

...
IdOpenSSLSetLibPath(FDocumentsPath);

SSLHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
SMTP:= TIdSMTP.Create(nil);
MSG:= TIdMessage.Create(nil);

try
  SSLHandler.SSLOptions.Method:= sslvSSLv23;
  SSLHandler.SSLOptions.Mode := sslmClient;

  SMTP.IOHandler := SSLHandler;
  SMTP.UseTLS:= utUseImplicitTLS;
  SMTP.AuthType:= satDefault;

  SMTP.Port:= 465;
  SMTP.Host:= xxx.xxx.xxx.xxx;
  SMTP.Username:= xxxxx;
  SMTP.Password:= xxxxx;

  SMTP.ConnectTimeout:= 30000;
  SMTP.ReadTimeout:= 30000;

  try
    SMTP.Connect;
  except
  end;

  ...
finally
  SMTP.Disconnect;
  UnLoadOpenSSLLibrary;

  FreeAndNil(MSG);
  FreeAndNil(SSLHandler);
  FreeAndNil(SMTP);
end;

ConnectTimeoutTIdIOHandlerStack 实现,因此同样适用于所有 TCP 客户端组件(IOW、TIdFTPTIdSMTP 使用完全相同的超时逻辑)。

但是,您必须考虑到 ConnectTimeout 仅适用于实际连接尝试(对套接字 API connect() 函数的调用)。它不适用于将主机名解析为 IP 地址所需的时间,也不适用于在监视超时时创建和拆除执行实际连接的工作线程所需的时间。所以 ConnectTimeout 不准确。

30 秒超时耗时 105 秒可能意味着 DNS 需要很长时间来解析主机名,或者可能意味着套接字 API 没有及时中止 connect() 调用一旦超时结束。调试代码以查看实际花费的时间。检查 OnStatus 事件以查看 hsResolvinghsConnecting 通知之间以及套接字无法连接到服务器时 hsConnecting 通知与后续异常之间经过的时间.