3

代码在 Windows 8 上停止运行。它在 Windows7、Windows XP 上运行良好...我找到了解决此问题的方法:在 Windows 兼容模式下启动应用程序:Windows XP (Service Pack 3) - 代码正常工作。如果 Windows 兼容模式为 Windows 7,则代码不起作用。我以管理员身份运行应用程序。已经尝试关闭防病毒和防火墙。我可以使用另一个 smtp 客户端(例如 .Net SmtpClient)发送具有相同参数的电子邮件。该问题在不同的 Windows 8 计算机(家庭、办公室)上重现。我创建了简单的测试应用程序。代码在 Delphi XE、Indy 10.5.7 上编写,OpenSSL 1.0.1.3 dll 放在 test.exe 文件夹中。

有任何想法吗?

代码:

SSLHandler.MaxLineAction := maException;
SSLHandler.SSLOptions.Method := sslvTLSv1;
SSLHandler.SSLOptions.Mode := sslmUnassigned;
SSLHandler.SSLOptions.VerifyMode := [];
SSLHandler.SSLOptions.VerifyDepth := 0;
SSLHandler.OnStatusInfo := IdSSLIOHandlerSocketOpenSSL1StatusInfo;

SMTP.IOHandler := SSLHandler;
SMTP.Host := 'smtp.gmail.com';
SMTP.Port := 587;
SMTP.UseTLS := utUseExplicitTLS;
SMTP.Username := FromAddress;
SMTP.Password := AuthPassword;

Email.From.Address := FromAddress;
Email.Recipients.EmailAddresses := ToAddress;
Email.Subject := Subject;
Email.Body.Text := Body;

SMTP.Connect;
SMTP.Send(Email);
SMTP.Disconnect;

输出:

SSL 状态:“之前/连接初始化”

SSL 状态:“之前/连接初始化”

SSL 状态:“SSLv3 写入客户端 hello A”

SSL 状态:“SSLv3 读取服务器你好 A”

EIdSocketError 与消息“套接字错误 #10060 连接超时。”

4

4 回答 4

7

它是 IdHTTP 的 ReadTimeout。默认情况下它为 -1,不适用于 Windows 8。将其设置为任何正值,如 15000 毫秒或 30000 将解决问题。

请注意,您需要以编程方式在 IdHTTP 对象上设置数值。不要尝试通过对象检查器设置绑定的 IoHandler,因为它不会以这种方式工作。

例子:

  IdHTTP1.ReadTimeout := 30000;

一个告诉 Indy 在其套接字操作上使用无限超时。但是,当连接断开时,为了解决 Vista+ 上 OpenSSL 中的死锁,如果 ReadTimeout <= 0,TIdSSLIOHandlerSocketOpenSSL 会在较低的套接字层强制超时 30 秒。}

Bob Daneshfar 在此论坛上发布的解决方案。

于 2013-07-19T20:30:27.930 回答
1

最后我发现这是印地相关的问题。升级到 Indy 10.5.8 或 10.5.9 可解决此问题。

谢谢大家的建议。

于 2013-02-13T11:43:47.847 回答
0

由于您可以使用 .NET 类成功发送电子邮件SmtpClient,因此我建议您使用数据包嗅探器(例如 Wireshark)来查看SmtpClient的网络流量并将其与 Indy/OpenSSL 的网络流量进行比较,看看到底有什么区别。在 OpenSSL 的 TLSv1 握手期间发生了一些事情,而这并没有发生SmtpClient,所以去看看他们的握手实际上是什么样子的。

于 2013-02-07T21:16:36.183 回答
0

您确定您已将 OpenSSL 库与您的应用程序一起分发(例如“libeay32.dll”和“ssleay32.dll”)吗?

当您忘记这些时,您也会遇到超时,因为 OpenSSL 库的错误未正确传输到外部 IO 对象(如 TIdSMTP 或 TIdHTTP)。

要检查 Indy 的 OpenSLL 是否可以加载,我使用以下代码(当 SSL 不可用时会引发错误) - 使用单元“IdSSLOpenSSL”

TIdSSLContext.Create.Free; // Raises an error, when unable to load SSL lib and such

您还可以插入 OpenSSL 标头单元“IdSSLOpenSSLHeader”并尝试手动加载库并检查它是否可以:

if not IdSSLOpenSSLHeaders.Load then ; // Raises no error, but return 'true' when it can load
于 2014-09-10T13:02:12.277 回答