1

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

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

使用 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;
4

1 回答 1

2

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

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

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

于 2017-04-11T16:04:38.333 回答