简体   繁体   English

使用 indy 组件 delphi xe2 SSL 协商失败发送电子邮件

[英]Send email using indy component delphi xe2 SSL negotiation faild

I tried with Indy component to send email in XE2, and it works fine on my laptop that I compiled my project on.我尝试使用 Indy 组件在 XE2 中发送电子邮件,它在我编译项目的笔记本电脑上运行良好。

But if I take my exe project to another PC, it shows an error message但是如果我将我的 exe 项目带到另一台 PC,它会显示一条错误消息

Connection closed gracefully连接正常关闭

or, sometimes I get或者,有时我得到

SSL Negotiation failed 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;

DO NOT set the SSL.Destination , SSL.Host , or SSL.Port properties manually!不要手动设置SSL.DestinationSSL.HostSSL.Port属性! TIdTCPClient.Connect() handles that for you. TIdTCPClient.Connect()为您处理。 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?此外,您不认为将SSL.Destination/Host设置为smtp.gmail.com而是将SMTP.Host设置为smtp.live.com吗? Gmail and Live are not the same service provider. Gmail 和 Live 不是同一个服务提供商。

Also, SSL.SSLOptions.Mode should be set to sslmClient instead of sslmUnassigned .此外, SSL.SSLOptions.Mode应设置为sslmClient而不是sslmUnassigned Not too important, TIdSSLIOHandlerSocketOpenSSL will simply flip it when it configures the connection.不太重要, TIdSSLIOHandlerSocketOpenSSL将在配置连接时简单地翻转它。 But you should do it anyway, since you know your code is acting as a client.但是无论如何您都应该这样做,因为您知道您的代码是作为客户端运行的。

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.最后,尝试设置SMTP.UseTLS设置之前SMTP.Port ,如设置UseTLS可能改变Port ,所以你要确保你真的连接到您所期待的正确的端口。

With that said, the SSL Negotiation failed error means the TLS handshake was started but failed part-way through the negotiation.话虽如此, SSL Negotiation failed错误意味着 TLS 握手已启动,但在协商过程中中途失败。 Try assigning handlers to TIdSSLIOHandlerSocketOpenSSL 's OnStatusInfo/Ex events to see how far the handshake is actually getting.尝试将处理程序分配给TIdSSLIOHandlerSocketOpenSSLOnStatusInfo/Ex事件,以查看握手实际达到的程度。 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 10 版本,请尝试查看引发的异常的InnerException属性,它可能会为您提供有关在之后引发EIdTLSClientTLSHandShakeFailed异常之前出了什么问题的线索。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM