问题描述
我正在使用 SmtpClient
库通过以下方式发送电子邮件:
I am using the SmtpClient
library to send emails using the following:
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".
The code works fine in my test environment, but when I use production SMTP servers, the code fails with an SmtpException
"Failure sending mail." with an inner IOException
"Unable to read data from the transport connection: net_io_connectionclosed".
我已经确认防火墙不是问题.端口在客户端和服务器之间打开得很好.我不确定还有什么可能引发此错误.
I've confirmed that firewalls are not an issue. The port opens just fine between the client and the server. I'm not sure what else could throw this error.
推荐答案
Super Redux 版本
尝试使用端口 587 而不是 465.端口 465 在技术上已被弃用.
Try port 587 instead of 465. Port 465 is technically deprecated.
经过一堆数据包嗅探后,我想通了.首先,这是一个简短的答案:
After a bunch of packet sniffing I figured it out. First, here's the short answer:
.NET SmtpClient
仅支持通过 STARTTLS 进行加密.如果设置了 EnableSsl
标志,则服务器必须使用 STARTTLS 响应 EHLO,否则将抛出异常.请参阅 MSDN 文档了解更多详情.
The .NET SmtpClient
only supports encryption via STARTTLS. If the EnableSsl
flag is set, the server must respond to EHLO with a STARTTLS, otherwise it will throw an exception. See the MSDN documentation for more details.
其次,为将来偶然发现此问题的人提供的快速 SMTP 历史课程:
Second, a quick SMTP history lesson for those who stumble upon this problem in the future:
过去,当服务还想提供加密时,它们被分配了一个不同的端口号,并在该端口号上立即启动了 SSL 连接.随着时间的推移,他们意识到为一个服务浪费两个端口号是愚蠢的,他们设计了一种服务方法,允许使用 STARTTLS 在同一个端口上进行明文和加密.通信将使用明文开始,然后使用 STARTTLS 命令升级到加密连接.STARTTLS 成为 SMTP 加密的标准.不幸的是,在实施新标准时总是会发生这种情况,与那里的所有客户端和服务器的兼容性都是大杂烩.
Back in the day, when services wanted to also offer encryption they were assigned a different port number, and on that port number they immediately initiated an SSL connection. As time went on they realized it was silly to waste two port numbers for one service and they devised a way for services to allow plaintext and encryption on the same port using STARTTLS. Communication would start using plaintext, then use the STARTTLS command to upgrade to an encrypted connection. STARTTLS became the standard for SMTP encryption. Unfortunately, as it always happens when a new standard is implemented, there is a hodgepodge of compatibility with all the clients and servers out there.
在我的例子中,我的用户试图将软件连接到强制立即 SSL 连接的服务器,这是 Microsoft 在 .NET 中不支持的旧方法.
In my case, my user was trying to connect the software to a server that was forcing an immediate SSL connection, which is the legacy method that is not supported by Microsoft in .NET.
这篇关于SmtpException:无法从传输连接读取数据:net_io_connectionclosed的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!