使用 indy 组件 delphi xe2 SSL 协商发送电子邮件失败 [英] Send email using indy component delphi xe2 SSL negotiation faild

查看:28
本文介绍了使用 indy 组件 delphi xe2 SSL 协商发送电子邮件失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试使用 Indy 组件在 XE2 中发送电子邮件,它在我编译项目的笔记本电脑上运行良好.

I tried with Indy component to send email in XE2, and it works fine on my laptop that I compiled my project on.

但是如果我将我的 exe 项目带到另一台 PC 上,它会显示一条错误消息

But if I take my exe project to another PC, it shows an error message

连接正常关闭

或者,有时我会得到

SSL 协商失败

其实我尝试了很多次来解决我的问题,但我不能.

Actually I tried many times to solve my problem, but I can't.

这是我的代码 - 我的错误在哪里?我需要一个实用的解决方案.

This is my code - where is my mistake? I need a practical solution.

procedure Gmail(username, password, totarget, subject, body :string);
var
   DATA : TIdMessage;
   SMTP : TIdSMTP;
   SSL : TIdSSLIOHandlerSocketOpenSSL;
   result:Boolean;
begin
   try
      SMTP := TIdSMTP.Create(nil);
      DATA := TIdMessage.Create(nil);
      SSL := TIdSSLIOHandlerSocketOpenSSL.Create(nil);

      SSL.Destination := 'smtp.gmail.com:587';
      SSL.Host := 'smtp.gmail.com';
      //  SSL.MaxLineAction.maException;
      SSL.Port:= 587;
      SSL.SSLOptions.Method := sslvTLSv1;
      SSL.SSLOptions.Mode := sslmUnassigned;
      SSL.SSLOptions.VerifyMode :=  [];
      SSL.SSLOptions.VerifyDepth := 0;

      DATA.From.Address := username;
      DATA.Recipients.EMailAddresses := totarget;
      DATA.Subject := subject;
      DATA.Body.Text := body;

      if FileExists('D:Test1.txt') then
         TIdAttachmentFile.Create(DATA.MessageParts, 'D:Test1.txt');

      SMTP.IOHandler := SSL;
      SMTP.Host := 'smtp.live.com';
      SMTP.Port := 587 ;
      SMTP.Username := username;
      SMTP.Password := password;
      //  SMTP.SASLMechanisms;
      SMTP.UseTLS := utUseExplicitTLS;

      try
         try
           SMTP.Connect;
           SMTP.Send(DATA);
           Result := True;
         except
           on E:Exception do
           begin
               ShowMessage('Cannot send E-Mail: ' + E.Message);
               Result := False;
           end;
         end;
      finally
         if SMTP.Connected then SMTP.Disconnect;
      end;
  except
    on E : Exception do
    begin
      ShowMessage('Error in the function SendEmailDelphi: ' + E.Message);
      Result := False;
    end;
  end;

end;

procedure TForm1.FormCreate(Sender: TObject);
begin
Timer1.Enabled:= True;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
mail_username := 'email@gmail.com';
mail_password := 'pass';
mail_to := 'email@gmail.com';
mail_subject := 'Text email from Delphi project';
mail_body := 'this is a test email sent from Delphi project, do not reply';

 try
   begin
     Gmail(mail_username, mail_password, mail_to , mail_subject, mail_body);
   end;
 finally

 end;
end;

推荐答案

请勿设置 SSL.DestinationSSL.HostSSL.Port 属性手动!TIdTCPClient.Connect() 为您处理.此外,您不觉得将 SSL.Destination/Host 设置为 smtp.gmail.com 但设置 SMTP.Host 改为 smtp.live.com?Gmail 和 Live 不是同一个服务提供商.

DO NOT set the SSL.Destination, SSL.Host, or SSL.Port properties manually! TIdTCPClient.Connect() handles that for you. Besides, don't you think it's odd that you are setting SSL.Destination/Host to smtp.gmail.com but are setting SMTP.Host to smtp.live.com instead? Gmail and Live are not the same service provider.

此外,SSL.SSLOptions.Mode 应设置为 sslmClient 而不是 sslmUnassigned.不太重要,TIdSSLIOHandlerSocketOpenSSL 会在配置连接时简单地翻转它.但无论如何你都应该这样做,因为你知道你的代码是作为客户端的.

Also, SSL.SSLOptions.Mode should be set to sslmClient instead of sslmUnassigned. Not too important, TIdSSLIOHandlerSocketOpenSSL will simply flip it when it configures the connection. But you should do it anyway, since you know your code is acting as a client.

最后,尝试设置 SMTP.UseTLS before 设置 SMTP.Port,作为设置 UseTLS 可能改变端口,所以你要确保你真的连接到你期望的正确端口.

And lastly, try setting SMTP.UseTLS before setting SMTP.Port, as setting UseTLS may change the Port, so you want to make sure you are really connecting to the correct port you are expecting.

话虽如此,SSL Negotiation failed 错误意味着 TLS 握手已启动,但在协商过程中失败.尝试将处理程序分配给 TIdSSLIOHandlerSocketOpenSSLOnStatusInfo/Ex 事件,以查看握手的实际进展情况.如果您使用的是相对现代的 Indy 10 版本,请尝试查看引发的异常的 InnerException 属性,它可能会为您提供关于 EIdTLSClientTLSHandShakeFailed 之前出现问题的线索之后引发了异常.

With that said, the SSL Negotiation failed error means the TLS handshake was started but failed part-way through the negotiation. Try assigning handlers to TIdSSLIOHandlerSocketOpenSSL's OnStatusInfo/Ex events to see how far the handshake is actually getting. And if you are using a relatively modern version of Indy 10, try looking at the raised exception's InnerException property, it might give you a clue as to what went wrong before the EIdTLSClientTLSHandShakeFailed exception was raised afterwards.

这篇关于使用 indy 组件 delphi xe2 SSL 协商发送电子邮件失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆