代码在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写客户端问候A”
SSL状态:“SSLv3读取服务器问候语A”
EIdSocketError,消息'Socket Error#10060 Connection time out out。'
答案 0 :(得分:7)
这是IdHTTP的ReadTimeout。默认情况下,它为-1,不适用于Windows 8.将其设置为15000ms或30000之类的正值可以解决问题。
请注意,您需要以编程方式在IdHTTP对象上设置数值。不要尝试通过对象检查器设置绑定的IoHandler,因为它不会以这种方式工作。
示例:
IdHTTP1.ReadTimeout := 30000;
One告诉Indy在其套接字操作上使用无限超时。但是,要在连接断开时在Vista +上解决OpenSSL中的死锁问题,如果ReadTimeout为< = 0,TIdSSLIOHandlerSocketOpenSSL会在较低的套接字层强制执行30秒的超时。}
Bob Daneshfar在this forum上发布的解决方案。
答案 1 :(得分:1)
最后我发现它与Indy有关。 升级到Indy 10.5.8或10.5.9可以解决问题。
感谢大家的建议。
答案 2 :(得分:0)
由于您可以使用.NET SmtpClient
类成功发送电子邮件,我建议您使用数据包嗅探器(如Wireshark)查看SmtpClient
的网络流量并将其与Indy / OpenSSL进行比较网络流量,看看到底有什么不同。在OpenSSL的TLSv1握手期间发生了一些事情,SmtpClient
没有发生,所以去看看他们的握手实际上是什么样的。
答案 3 :(得分:0)
您确定已经使用应用程序(如'libeay32.dll'和'ssleay32.dll')分发了OpenSSL库吗?
当您忘记这些时,您也会遇到超时,因为OpenSSL库的错误未正确传输到外部IO对象(如TIdSMTP或TIdHTTP)。
要检查Open的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