You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复Delphi发送邮件时的Must issue a STARTTLS command first错误

解决Delphi发送Gmail邮件时的"Must issue a STARTTLS command first"错误

本人Delphi编程经验有限,对当前要解决的问题了解甚少。我需要根据程序需求向用户发送一封包含“货运详情”的邮件,但运行代码时出现“Must issue a STARTTLS command first”错误。我已填写所有必要的空字符串内容并尝试设置自定义应用密码,但错误依然存在。

报错代码

procedure TForm1.FormCreate(Sender: TObject);
var
  smtp: TIdSMTP;
  msg: TIdMessage;
  sslHandler: TIdSSLIOHandlerSocketOpenSSL;
begin
  try
    smtp := TIdSMTP.Create(nil);
    msg := TIdMessage.Create(nil);
    sslHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
    try
      // Configure SSL handler
      sslHandler.SSLOptions.Method := sslvTLSv1_2;
      sslHandler.SSLOptions.Mode := sslmUnassigned;
      // Configure SMTP settings
      smtp.IOHandler := sslHandler;
      smtp.Host := 'smtp.gmail.com';
      smtp.Port := 587;
      smtp.Username := '';
      smtp.Password := '';

      // Create email message
      msg.From.Address := '';
      msg.Recipients.Add.Address := '';
      msg.Subject := 'Delphi Test Email';

      with TIdText.Create(msg.MessageParts, nil) do
      begin
        Body.Text := 'This is a test';
      end;
      // Connect and send email
      smtp.Connect;
      try
        smtp.Send(msg);
      finally
        smtp.Disconnect;
      end;
    finally
      // Clean up
      sslHandler.Free;
      msg.Free;
      smtp.Free;
    end;
  except
    on E: Exception do
      ShowMessage('An error occurred: ' + E.Message);
  end;
end;

当前uses子句

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, IdComponent, IdTCPConnection,
  IdTCPClient, IdExplicitTLSClientServerBase, IdMessageClient, IdSMTPBase,
  IdBaseComponent, IdSMTP, IdMessage, IdText, IdSSLOpenSSL, IdIOHandler,
  IdIOHandlerSocket, IdIOHandlerStack, IdSSL;

修复步骤

  • 启用STARTTLS:Gmail的587端口要求使用显式TLS,必须设置smtp.UseTLS := utUseExplicitTLS,否则Indy不会触发STARTTLS命令。
  • 修正SSL模式:将sslHandler.SSLOptions.Mode改为sslmClient,明确这是客户端SSL连接模式。
  • 检查OpenSSL依赖:确保程序目录下存在对应版本的OpenSSL动态库(32位程序用libeay32.dll和ssleay32.dll,64位用libcrypto-1_1-x64.dll和libssl-1_1-x64.dll),Indy依赖这些库完成加密连接。

修改后的完整代码

procedure TForm1.FormCreate(Sender: TObject);
var
  smtp: TIdSMTP;
  msg: TIdMessage;
  sslHandler: TIdSSLIOHandlerSocketOpenSSL;
begin
  try
    smtp := TIdSMTP.Create(nil);
    msg := TIdMessage.Create(nil);
    sslHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
    try
      // Configure SSL handler
      sslHandler.SSLOptions.Method := sslvTLSv1_2;
      sslHandler.SSLOptions.Mode := sslmClient; // 改为客户端模式
      // Configure SMTP settings
      smtp.IOHandler := sslHandler;
      smtp.Host := 'smtp.gmail.com';
      smtp.Port := 587;
      smtp.Username := '你的Gmail账号';
      smtp.Password := '你的应用密码';
      smtp.UseTLS := utUseExplicitTLS; // 启用显式TLS(STARTTLS)

      // Create email message
      msg.From.Address := '你的Gmail账号';
      msg.Recipients.Add.Address := '收件人邮箱';
      msg.Subject := '货运详情';

      with TIdText.Create(msg.MessageParts, nil) do
      begin
        Body.Text := '这里填写货运详情内容';
      end;
      // Connect and send email
      smtp.Connect;
      try
        smtp.Send(msg);
        ShowMessage('邮件发送成功');
      finally
        smtp.Disconnect;
      end;
    finally
      // Clean up
      sslHandler.Free;
      msg.Free;
      smtp.Free;
    end;
  except
    on E: Exception do
      ShowMessage('An error occurred: ' + E.Message);
  end;
end;

内容的提问来源于stack exchange,提问作者Eclipse

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 14:33:16