一尘不染

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

c#

我正在使用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");

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

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


阅读 2342

收藏
2020-05-19

共1个答案

一尘不染

编辑:超级Redux版本

请尝试使用端口587而不是465。在技术上,不建议使用端口465。


一堆包嗅探后,我想通了。首先,这是一个简短的答案:

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

其次,面向那些在将来遇到此问题的人提供了一个简短的SMTP历史课程:

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

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

2020-05-19