Indy10 + OpenSSL:发送电子邮件代码在Windows 8上停止工作

时间:2013-02-07 17:09:19

标签: delphi openssl indy10

代码在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。'

4 个答案:

答案 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
相关问题