C# 中的零星 SMTP 电子邮件发送失败

Posted

技术标签:

【中文标题】C# 中的零星 SMTP 电子邮件发送失败【英文标题】:Sporadic SMTP email sending failures in C# 【发布时间】:2021-11-27 20:59:06 【问题描述】:

我有一个应用程序已经运行了一段时间,偶尔用户可以触发发送电子邮件,它使用 SmtpClient 和 Office 365。

从大约 3 天前开始,我们在发送电子邮件时遇到了一些失败,这似乎是全天随机发生的。错误总是

“验证失败,因为远程方关闭了传输流。”

我在下面附上了代码和完整的堆栈跟踪。有谁知道这个错误是什么意思?

string fromEmailAddress = ProgramHelpers.SMTPFrom; // for 365 have to use the from email setup in the ini. NR 28/9/20
        int portNumber = ProgramHelpers.SMTPPort == "" ? 25 : Convert.ToInt32(ProgramHelpers.SMTPPort);
        bool ssl = true;
 
        using (SmtpClient smtp = new SmtpClient(ProgramHelpers.SMTPHost))
        
            smtp.Port = portNumber;
            smtp.EnableSsl = ssl;
            var user = ProgramHelpers.SMTPUser;
            if (user != string.Empty)
                smtp.Credentials = new NetworkCredential(user, ProgramHelpers.SMTPPassword);
 
            MailMessage m = new MailMessage();
            m.From = new MailAddress(fromEmailAddress);
 
            if (string.IsNullOrWhiteSpace(to))
            
                var warningMessage = $"Cannot send email with subject 'subject' as the 'to' email address is blank";
                _logger.Warn(warningMessage);
                return Result.Failure(new Exception(warningMessage));
            
 
            foreach (var email in to.Split(';', ',').Where(a => !a.IsNullOrWhiteSpace()))
                m.To.Add(email.Trim());
 
            m.Subject = subject;
            m.Body = body;

            m.IsBodyhtml = isHtml;
            if (fileAttachment != null)
            
                m.Attachments.Add(fileAttachment);
            
 
            if (additionalAttachment != null && additionalAttachment.Trim() != "")
            
                m.Attachments.Add(new Attachment(additionalAttachment));
            
 
            //Try and send the message
            try
            
                smtp.Send(m);
                return Result.Success();
            
            //Catch any errors...
            catch (Exception x)
            
                var ex = new SmtpException($"Failed to send mail with subject m.Subject to m.To.FirstOrDefault() with SMTP server smtp.Host/smtp.Port (SSL: smtp.EnableSsl", x);
                _logger.Error(ex, ex.Message);
                return Result.Failure(x);
            
        

堆栈跟踪:

System.Net.Mail.SmtpException:发送邮件失败。 ---> System.IO.IOException: 身份验证失败,因为远程方已关闭传输流。 在 System.Net.Security.SslState.StartReadFrame(字节 [] 缓冲区,Int32 读取字节,AsyncProtocolRequest asyncRequest) 在 System.Net.Security.SslState.StartReceiveBlob(字节 [] 缓冲区,AsyncProtocolRequest asyncRequest) 在 System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken 消息,AsyncProtocolRequest asyncRequest) 在 System.Net.Security.SslState.StartSendBlob(字节 [] 传入,Int32 计数,AsyncProtocolRequest asyncRequest) 在 System.Net.Security.SslState.ForceAuthentication(布尔接收第一,字节 [] 缓冲区,AsyncProtocolRequest asyncRequest) 在 System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResultlazyResult) 在 System.Net.TlsStream.CallProcessAuthentication(对象状态)

【问题讨论】:

我最近也遇到了这个错误。不会一直随机发生。 看看这篇文章。它有一个可能的解决方案...***.com/questions/43240611/… 【参考方案1】:

我遇到了同样的错误,并将其追溯到我们的服务被硬编码为使用 TLS 1.0 来加密 SMTP 连接,而 Office 365 正在关闭对 TLS 1.0 和 TLS 1.1 的支持并强制执行 TLS 1.2.

您可以在 this stack overflow question 上阅读更多关于此特定异常的信息,并在 the microsoft docs 上阅读更多信息,了解他们正在关闭 TLS 1.0 和 1.1。没有官方文档,但我认为过去几周发生了一些变化,因为我们的服务在 10 月 1 日左右之前一直运行良好,但从那时起就变得非常不可靠(但仍然可以正常工作)。

您可以在此处查看有关 Office 365 中 TLS 使用情况的报告:https://protection.office.com/mailflow/dashboard。只需展开“SMTP Auth Clients”报告,您就会看到 TLS 使用情况的明细。理想情况下,您希望所有内容都使用 TLS 1.2,因此如果您看到任何使用 TLS 1.0 或 1.1 的内容,您需要尽快更新。

假设这可以解释您的问题,我不确定您在具体情况下需要做什么才能切换到 TLS 1.2,但this stack overflow question 应该会给您一些尝试的线索。

【讨论】:

【参考方案2】:

微软发布了这个(source):

我们充分意识到许多客户不会注意到 多个消息中心帖子和博客帖子,并且不知道 仍在使用 TLS1.0 提交消息的客户端或设备。 考虑到这一点,从 2021 年 9 月开始,我们将拒绝一个小 使用 TLS1.0 进行 SMTP AUTH 的连接百分比。客户 应该重试任何其他可能发生的临时错误 提交。随着时间的推移,我们将增加被拒绝的百分比 连接,导致延迟发送越来越多的客户 应该注意。

似乎可能是导致此问题的原因。

【讨论】:

以上是关于C# 中的零星 SMTP 电子邮件发送失败的主要内容,如果未能解决你的问题,请参考以下文章

发送 smtp gmail 电子邮件“发送邮件失败”

如何使用 Gmail SMTP 服务器在 C# 中发送邮件? [复制]

在 C# 中使用不带 TO 的 BCC 通过 SMTP 发送邮件

使用 C# 通过 Gmail SMTP 服务器发送电子邮件

linux PHPMailer 发送邮件sendmail 发邮件失败问题

SMTP Connect() 失败。邮件未发送。邮件程序错误:SMTP Connect() 失败