【问题标题】:STARTTLS error while sending email using Indy in Delphi XE在 Delphi XE 中使用 Indy 发送电子邮件时出现 STARTTLS 错误
【发布时间】:2011-12-04 18:33:52
【问题描述】:

我正在尝试使用以下代码从我的应用程序发送电子邮件:

  Var
  MailMessage : TIdMessage;
  SMTP        : TIdSMTP
   .
   .
   .
 //setup SMTP
 SMTP.Host := 'smtp.gmail.com';
 SMTP.Port := 25;
 //setup mail message
 MailMessage.From.Address := 'fromMe@gmail.com';
 MailMessage.Recipients.EMailAddresses := 'ToSomeOne@hotmail.com';
 MailMessage.Subject := 'Test';
 MailMessage.Body.Text := 'Hello, It is Just for test';

 SMTP.Connect;
 SMTP.Send(MailMessage);

当我运行它时,它会产生以下错误

**ERROR: Must issue a STARTTLS command first. i29sm34080394wbp.22**

我该如何解决这个问题?

【问题讨论】:

标签: delphi delphi-xe indy10


【解决方案1】:

smtp.gmail.com 强制您使用使用 STARTTLS 的加密连接。

Indy 9 不直接支持 STARTTLS,但 indy 10 支持。

在 Indy 10 中,在连接到服务器之前,您必须分配一个 启用S​​SL的IOHandler,如TIdSSLIOHandlerSocketOpenSSL

见:http://www.indyproject.org/docsite/html/frames.html?frmname=topic&frmfile=TIdSSLIOHandlerSocketOpenSSL.html

添加以下代码:

var
...
SSLHandler: TIdSSLIOHandlerSocketOpenSSL;

SSLHandler:= TIdSSLIOHandlerSocketOpenSSL.Create(Form1);
SMTP.IOHandler:= SSLHandler;
SMTP.UseTLS:= utUseExplicitTLS;
SMTP.Username:= 'username';
SMTP.Password:= 'password';
SMTP.Port:= 587; 

如果您只是将 SMTP 发送到未加密的 SMTP 处理程序(您的 ISP 的 SMTP),您将不会遇到此问题。

【讨论】:

  • @Johna:说 Indy 9 不支持此 是错误的。 Indy 9 确实支持 SSL 加密,只是不支持 GMail 的 SMTP 服务器所需的 STARTTLS 命令。不过,您可以使用几行额外的代码手动发送 STARTTLS 命令。至于OnGetPassword 事件,这仅适用于使用受密码保护的 SSL 证书的情况(GMail 不是这种情况)。
  • @RemyLebeau-TeamB,感谢您指出这一点,我已经有一段时间没有使用 Indy 了。
  • @RemyLebeau 是否可以使用 Indy 8 手动发送 STARTTLS?我有一个使用 Indy 8 的应用程序。我可以使用 SSL 连接发送电子邮件,但前提是服务器使用隐式 TLS。我想添加对 STARTTLS 的支持。如果可能的话,请告诉我如何
【解决方案2】:

该错误是因为 Gmail 使用 SSL 和 TLS。您将需要使用 Indy 的 SSL IO 处理程序以及适合您的 Indy 版本的 OpenSSL DLL's

有一个让这个工作的教程here

【讨论】:

    【解决方案3】:

    通过将答案放在一起,您可以获得以下代码。不要忘记 Nathanial Woolls 提到 herelibeay32.dllssleay32.dll 库从 here 放到您的项目文件夹或 following places 的路径中。

    uses
      IdMessage, IdSMTP, IdSSLOpenSSL, IdGlobal, IdExplicitTLSClientServerBase;
    
    procedure SendEmail(const Recipients: string; const Subject: string; const Body: string);
    var
      SMTP: TIdSMTP;
      Email: TIdMessage;
      SSLHandler: TIdSSLIOHandlerSocketOpenSSL;
    begin
      SMTP := TIdSMTP.Create(nil);
      Email := TIdMessage.Create(nil);
      SSLHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
    
      try
        SSLHandler.MaxLineAction := maException;
        SSLHandler.SSLOptions.Method := sslvTLSv1;
        SSLHandler.SSLOptions.Mode := sslmUnassigned;
        SSLHandler.SSLOptions.VerifyMode := [];
        SSLHandler.SSLOptions.VerifyDepth := 0;
    
        SMTP.IOHandler := SSLHandler;
        SMTP.Host := 'smtp.gmail.com';
        SMTP.Port := 587;
        SMTP.Username := 'yourusername@gmail.com';
        SMTP.Password := 'yourpassword';
        SMTP.UseTLS := utUseExplicitTLS;
    
        Email.From.Address := 'yourusername@gmail.com';
        Email.Recipients.EmailAddresses := Recipients;
        Email.Subject := Subject;
        Email.Body.Text := Body;
    
        SMTP.Connect;
        SMTP.Send(Email);
        SMTP.Disconnect;
    
      finally
        SMTP.Free;
        Email.Free;
        SSLHandler.Free;
      end;
    end;
    
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      SendEmail('recipient@whatever.com', 'Subject', 'Body');
    end;
    

    希望有帮助

    【讨论】:

    • 去掉SSLHandler.DestinationSSLHandler.HostSSLHandler.Port属性的分配。这些属性由Connect()自动填写。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-08
    • 2014-06-08
    • 1970-01-01
    • 2013-11-24
    • 2016-04-24
    • 2010-12-11
    相关资源
    最近更新 更多