SmtpException:无法从传输连接中读取数据:net_io_connectionclosed

Jak*_*e C 96 c# smtp

我正在使用该SmtpClient库使用以下内容发送电子邮件:

SmtpClient client = new SmtpClient();
client.Host = "hostname";
client.Port = 465;
client.DeliveryMethod = SmtpDeliveryMethod.Network;
client.UseDefaultCredentials = false;
client.EnableSsl = true;
client.Credentials = new NetworkCredential("User", "Pass);
client.Send("from@hostname", "to@hostname", "Subject", "Body");
Run Code Online (Sandbox Code Playgroud)

代码在我的测试环境中工作正常,但是当我使用生产SMTP服务器时,代码失败并显示SmtpException"发送邮件失败".内部IOException"无法从传输连接读取数据:net_io_connectionclosed".

我已经确认防火墙不是问题.端口在客户端和服务器之间打开很好.我不确定还有什么可能引发这个错误.

Jak*_*e C 177

编辑:超级Redux版本

尝试端口587而不是465.端口465在技术上已弃用.


经过一堆数据包嗅探后,我发现了它.首先,这是简短的回答:

.NET SmtpClient 支持通过STARTTLS进行加密.如果EnableSsl设置了该标志,则服务器必须使用STARTTLS响应EHLO,否则将引发异常.有关更多详细信息,请参阅MSDN文档.

第二,为将来偶然发现此问题的人提供快速的SMTP历史课程:

在当天,当服务还希望提供加密时,他们被分配了不同的端口号,并且在该端口号上,他们立即启动了SSL连接.随着时间的推移,他们意识到为一项服务浪费两个端口号是愚蠢的,他们设计了一种服务方式,允许使用STARTTLS在同一端口上进行明文和加密.通信将以明文开始,然后使用STARTTLS命令升级到加密连接.STARTTLS成为SMTP加密的标准.不幸的是,由于在实施新标准时总会发生这种情况,因此存在与所有客户端和服务器兼容的大杂烩.

就我而言,我的用户试图将软件连接到强制立即进行SSL连接的服务器,这是Microsoft在.NET中不支持的遗留方法.

  • 最简单的测试方法是尝试使用端口587而不是465.虽然有些SMTP服务器支持465上的TLS(有时甚至是25),但只需要端口587来支持TLS.除此之外,自1998年以来,已经弃用了端口465(http://en.wikipedia.org/wiki/SMTPS),尽管实际上许多服务器已经为旧版客户端启用了它. (9认同)
  • 是的,更改为 587 就成功了。感谢您为我指明了正确的方向。 (2认同)
  • 587可以工作,尽管smtp.att.yahaoo.com说使用465。谢谢,老兄。 (2认同)

小智 61

把它放在我的方法的开头为我解决了这个问题

System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12
Run Code Online (Sandbox Code Playgroud)

  • 这似乎是 2022 年的正确答案。我还添加了一些其他协议> ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | 安全协议类型.Tls | 安全协议类型.Tls11 | 安全协议类型.Tls12; (11认同)

ADM*_*-IT 18

将端口从465更改为587,它将起作用.

  • 我不确定发生了什么,但这使我使用gmail smtp.你能解释一下为什么会这样吗? (3认同)

nol*_*ogo 17

对于任何偶然发现此帖子寻找解决方案并且您通过Azure设置SMTP sendgrid的人.

用户名不是您在azure中创建sendgrid对象时设置的用户名.要查找您的用户名;

  • 单击azure中的sendgrid对象,然后单击"管理".您将被重定向到SendGrid站点.
  • 确认您的电子邮件,然后复制那里显示的用户名..这是一个自动生成的用户名.
  • 将SendGrid中的用户名添加到web.config文件中的SMTP设置中.

希望这可以帮助!

  • 这可能看起来很愚蠢,但您可能要检查的其他内容是密码是否适用于SMTP SendGrid设置.我们的设置最初正在运行,然后有一天我们开始收到OP的异常消息.搜索WWW主要指向查看其他SMTP服务器配置,最终证明密码不正确.团队中的某个人已将配置文件中的密码更改为第一个字母为非大写字母的变体. (2认同)

Bil*_*ney 8

您可能还需要更改Gmail帐户中"安全性较低的应用"设置.EnableSsl,使用端口587并启用"安全性较低的应用程序".如果您谷歌的安全性较低的应用程序部分有谷歌帮助页面,将链接到您的帐户页面.这是我的问题,但由于上面的所有答案,现在一切正常.


Mar*_*oso 8

特定于 Outlook Mailer 的答案

var SmtpClient = new SmtpClient{
                DeliveryMethod = SmtpDeliveryMethod.Network,
                Credentials = new System.Net.NetworkCredential("email", "password"),
                Port = 587,
                Host = "smtp.office365.com",
                EnableSsl = true }
Run Code Online (Sandbox Code Playgroud)

https://admin.exchange.microsoft.com/#/settings -> 单击“邮件流”

-> 检查 - 启用旧版 TLS 客户端的使用

-> 保存

在此输入图像描述


小智 7

我已经尝试了上面所有的答案,但是使用Office 365帐户仍然遇到此错误。当允许使用不太安全的应用程序时,该代码似乎可以与Google帐户和smtp.gmail.com一起正常工作。

我可以尝试其他建议吗?

这是我正在使用的代码

int port = 587;
string host = "smtp.office365.com";
string username = "smtp.out@mail.com";
string password = "password";
string mailFrom = "noreply@mail.com";
string mailTo = "to@mail.com";
string mailTitle = "Testtitle";
string mailMessage = "Testmessage";

using (SmtpClient client = new SmtpClient())
{
    MailAddress from = new MailAddress(mailFrom);
    MailMessage message = new MailMessage
    {
        From = from
    };
    message.To.Add(mailTo);
    message.Subject = mailTitle;
    message.Body = mailMessage;
    message.IsBodyHtml = true;
    client.DeliveryMethod = SmtpDeliveryMethod.Network;
    client.UseDefaultCredentials = false;
    client.Host = host;
    client.Port = port;
    client.EnableSsl = true;
    client.Credentials = new NetworkCredential
    {
        UserName = username,
        Password = password
    }; 
    client.Send(message);
}
Run Code Online (Sandbox Code Playgroud)

更新以及如何解决:

通过将Smtp客户端更改为Mailkit解决了问题。由于安全问题,现在不建议Microsoft使用System.Net.Mail Smtp客户端,而应该使用MailKit。使用Mailkit给我提供了更清晰的错误消息,使我可以理解找到问题(许可证问题)的根本原因。您可以通过以Nuget包的形式下载Mailkit

阅读有关Smtp客户端的文档以了解更多信息:https ://docs.microsoft.com/es-es/dotnet/api/system.net.mail.smtpclient?redirectedfrom=MSDN&view=netframework-4.7.2

这是我用MailKit实现SmtpClient的方法

        int port = 587;
        string host = "smtp.office365.com";
        string username = "smtp.out@mail.com";
        string password = "password";
        string mailFrom = "noreply@mail.com";
        string mailTo = "mailto@mail.com";
        string mailTitle = "Testtitle";
        string mailMessage = "Testmessage";

        var message = new MimeMessage();
        message.From.Add(new MailboxAddress(mailFrom));
        message.To.Add(new MailboxAddress(mailTo));
        message.Subject = mailTitle;
        message.Body = new TextPart("plain") { Text = mailMessage };

        using (var client = new SmtpClient())
        {
            client.Connect(host , port, SecureSocketOptions.StartTls);
            client.Authenticate(username, password);

            client.Send(message);
            client.Disconnect(true);
        }
Run Code Online (Sandbox Code Playgroud)


Gon*_*oug 5

去除

client.UseDefaultCredentials = false; 
Run Code Online (Sandbox Code Playgroud)

似乎为我解决了。