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

Delphi 11发送邮件时出现SSL negotiation failed错误求助

问题描述

我尝试使用一段Delphi代码发送邮件,但未成功。客户端能成功连接到服务器,但执行Send(IdMessage1)时,持续收到错误:两次socket error 10054 connection reset by peer,最终出现SSL negotiation failed。

PS1:在任意MAPI服务器(自建服务器、GMail、Yahoo等)上均会出现相同问题
PS2:SSL DLL已存在,且同一应用程序使用它们进行其他连接时无此问题。

涉事代码

procedure SendEmailClick(Sender: TObject);
var
    IdMessage1: TIdMessage;
    Attachmentfile: TIdAttachmentFile;
begin
// IO HANDLER SETTINGS //
With TIdSSLIOHandlerSocketOpenSSL.Create(nil) do
    begin
        Destination := 'mySrver.com:587';
        Host := 'mySrver.com';
        MaxLineAction := maException;
        Port := 587;
        SSLOptions.SSLVersions := [sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2];
        SSLOptions.Mode := sslmUnassigned;
        SSLOptions.VerifyMode := [];
        SSLOptions.VerifyDepth := 0;
    end;
//SETTING SMTP COMPONENT DATA //
with TIdSMTP.Create(nil) do begin
    Host := 'mySrver.com';
    Port := 587;
    Username := myMailAddress; // please change to your gmail address //
    Password := myPassword;
    IOHandler := TIdSSLIOHandlerSocketOpenSSL.create;
    AuthType := satDefault;
    UseTLS := utUseExplicitTLS;
// SETTING email MESSAGE DATA //
    IdMessage1:= TIdMessage.Create(nil);
    IdMessage1.Clear;
// add recipient list //
    with IdMessage1.Recipients.Add do
        begin
            Name := 'Recipient 1';
            Address := recipient1Address; // please change email address as required //
        end;
//add Attachment to mail //
    Attachmentfile := TIdAttachmentFile.Create(IdMessage1.MessageParts,'Τιμολόγιο 659.PDF');
    IdMessage1:= TIdMessage.Create(nil);
    IdMessage1.From.Address :=  myMailAddress;  // please change to your gmail address //;
    IdMessage1.Subject := 'Test Email Subject';
    IdMessage1.Body.Add('Test Email Body');
    IdMessage1.Priority := mpHigh;
    TRY
        Connect(); // no problem here. it connects always 
        Send(IdMessage1); // raises the error SSL negotiation failed
        ShowMessage('Email sent');
        Disconnect();
    except on e:Exception do
        begin
            ShowMessage(e.Message);
            Disconnect();
        end;
    END;
    IdMessage1.Free;
    IOHandler.Free;
end;
AttachmentFile.Free;
end;
问题分析与解决

你的代码存在几个关键错误,导致SSL协商失败:

  • 重复创建IdMessage1导致数据丢失:你先创建了一个IdMessage1并添加了收件人和附件,但随后又重新创建了新的IdMessage1实例,直接丢弃了之前的配置数据,同时造成原实例内存泄漏。
  • IOHandler配置无效:开头创建的TIdSSLIOHandlerSocketOpenSSL实例未赋值给任何变量,创建后直接被丢弃;给SMTP组件的IOHandler赋值时,新建的实例未配置SSL选项,默认配置不兼容服务器要求。
  • Attachment释放逻辑错误:重新创建IdMessage1后,原Attachmentfile已绑定到无效实例,后续释放可能引发问题。

修正后的代码

procedure SendEmailClick(Sender: TObject);
var
  IdMessage1: TIdMessage;
  Attachmentfile: TIdAttachmentFile;
  SMTP: TIdSMTP;
  SSLHandler: TIdSSLIOHandlerSocketOpenSSL;
begin
  // 创建并配置SSL Handler
  SSLHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
  try
    SSLHandler.SSLOptions.SSLVersions := [sslvTLSv1_2, sslvTLSv1_3]; // 优先使用新版TLS,适配主流服务器
    SSLHandler.SSLOptions.Mode := sslmClient;
    SSLHandler.SSLOptions.VerifyMode := [];
    SSLHandler.SSLOptions.VerifyDepth := 0;

    // 创建SMTP组件并配置
    SMTP := TIdSMTP.Create(nil);
    try
      SMTP.Host := 'mySrver.com';
      SMTP.Port := 587;
      SMTP.Username := myMailAddress;
      SMTP.Password := myPassword;
      SMTP.IOHandler := SSLHandler;
      SMTP.AuthType := satDefault;
      SMTP.UseTLS := utUseExplicitTLS;

      // 创建并配置邮件内容
      IdMessage1 := TIdMessage.Create(nil);
      try
        IdMessage1.Clear;
        IdMessage1.From.Address := myMailAddress;
        IdMessage1.Subject := 'Test Email Subject';
        IdMessage1.Body.Add('Test Email Body');
        IdMessage1.Priority := mpHigh;

        // 添加收件人
        with IdMessage1.Recipients.Add do
        begin
          Name := 'Recipient 1';
          Address := recipient1Address;
        end;

        // 添加附件
        Attachmentfile := TIdAttachmentFile.Create(IdMessage1.MessageParts, 'Τιμολόγιο 659.PDF');
        try
          // 连接并发送邮件
          SMTP.Connect;
          try
            SMTP.Send(IdMessage1);
            ShowMessage('Email sent');
          finally
            SMTP.Disconnect;
          end;
        finally
          Attachmentfile.Free;
        end;
      finally
        IdMessage1.Free;
      end;
    finally
      SMTP.Free;
    end;
  finally
    SSLHandler.Free;
  end;
end;

额外注意事项

  • 优先启用sslvTLSv1_2和sslvTLSv1_3,目前大部分邮件服务器已不再支持老旧的TLSv1.0和TLSv1.1。
  • 确保使用的Indy版本为较新的稳定版,旧版本可能存在SSL协商的兼容性问题。
  • 确认服务器SMTP端口对应的TLS模式:587端口通常使用utUseExplicitTLS,465端口使用utUseImplicitTLS,不要混淆。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 21:48:20