经过System.Net.Mail.SmtpClient
使用SSL/TLS协议发送邮件失败并报错
System.Net.Mail.SmtpException: Failure sending mailhtml
详细报错信息:git
System.Net.Mail.SmtpException: Failure sending mail. ---> System.IO.IOException: Unable to read data from the transport connection: The connection was closed. at System.Net.Mail.SmtpReplyReaderFactory.ProcessRead(Byte[] buffer, Int32 offset, Int32 read, Boolean readLine) at System.Net.Mail.SmtpReplyReaderFactory.ReadLines(SmtpReplyReader caller, Boolean oneLine) at System.Net.Mail.SmtpReplyReaderFactory.ReadLine(SmtpReplyReader caller) at System.Net.Mail.SmtpConnection.GetConnection(String host, Int32 port) at System.Net.Mail.SmtpTransport.GetConnection(String host, Int32 port) at System.Net.Mail.SmtpClient.GetConnection() at System.Net.Mail.SmtpClient.Send(MailMessage message) --- End of inner exception stack trace --- at System.Net.Mail.SmtpClient.Send(MailMessage message)
这个问题跟SSL/TLS的协议版本有关系,SSL演化到3.0以后仍是不够安全,所以又出现了SSL的升级版TLS协议,因为创建链接时的区别又分别被称为显示SSL和隐式SSL。SSL/TLS协议一般是结对出现SSL/TLS,不过你们仍是喜欢简称为SSL。github
目前最新版本是TLS 1.3,其余可用版本是TLS 1.2和TLS 1.1,其中TLS1.1计划于2020年弃用
因此,目前主流的邮箱服务商加密协议使用的都是TLS。
可是System.Net.Mail.SmtpClient
不支持较新的TLS协议,具体的TLS协议版本支持状况MSDN上并未找到相关说明web
截止到2020年3月受影响的框架版本:api
目前微软MSDN已经将System.Net.Mail.SmtpClient
标记为已过时(obsolete),但源码中并未标记,也并未给出替代实现。安全
System.Web.Mail.SmtpMail
虽然已被标记为已过时,可是毕竟他支持新的SSL/TLS协议。bash
不过,须要注意的是,System.Web.Mail.SmtpMail
,只适用于 .NET Framework(>=2.0)服务器
示例代码:框架
using System.Web.Mail; using System; namespace Ken.IO.Util { class Program { public static void Main (string[] args) { MailMessage mmsg = new MailMessage(); mmsg.Subject = "邮件测试主题ken.io"; mmsg.BodyFormat = MailFormat.Html; mmsg.Body = "邮件测试正文ken.io"; mmsg.BodyEncoding = Encoding.UTF8; //优先级 mmsg.Priority = MailPriority.High; //发件者邮箱地址 mmsg.From = "xxx@qq.com"; //收件人收箱地址 mmsg.To = "xxx@163.com"; mmsg.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate", "1"); //用户名 mmsg.Fields.Add("http://schemas.microsoft.com/cdo/configuration/sendusername", mmsg.From); //密码 mmsg.Fields.Add("http://schemas.microsoft.com/cdo/configuration/sendpassword", "password"); //端口 mmsg.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpserverport", 465); //使用SSL mmsg.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpusessl", "true"); //Smtp服务器 SmtpMail.SmtpServer = "smtp.qq.com"; SmtpMail.Send(mmsg); } } }
MailKit是一个开源的基于MimeKit的跨平台邮件收发类库,支持IMAP、POP三、SMTP。其中SmtpClient也支持TLS协议.测试
能够很好的支持 .NET Core以及 .NET Framework框架的邮件发送
安装Nuget Package
#.NET Core dotnet add package MailKit --version 2.5.1 #.NET Framework Install-Package MailKit -Version 2.5.1
示例代码:
using System; using MailKit.Net.Smtp; using MailKit; using MimeKit; namespace Ken.IO.Util { class Program { public static void Main (string[] args) { var message = new MimeMessage (); message.From.Add (new MailboxAddress ("test", "xxx@qq.com")); message.To.Add (new MailboxAddress ("test", "xxx@163.com")); message.Subject = "邮件测试"; //html or plain var bodyBuilder = new BodyBuilder (); bodyBuilder.HtmlBody = "<b>邮件测试html正文ken.io</b>"; bodyBuilder.TextBody = "邮件测试文本正文ken.io"; message.Body = bodyBuilder.ToMessageBody(); using (var client = new SmtpClient ()) { client.ServerCertificateValidationCallback = (s,c,h,e) => true; //smtp服务器,端口,是否开启ssl client.Connect ("smtp.qq.com", 465, true); client.Authenticate ("xxx@qq.com", "password"); client.Send (message); client.Disconnect (true); } } } }