SmtpClient无法发送;雷鸟可以
SmtpClient can't send; Thunderbird can
这应该很正常吧?
public static SmtpClient GetSmtpClient()
{
var client = new SmtpClient
{
Host = _smtpServer,
UseDefaultCredentials = false,
Credentials = new NetworkCredential(_smtpUsername, _smtpPassword),
Port = _smtpPort, // port 25
EnableSsl = _smtpSsl // false
};
return client;
}
...
var m = new MailMessage
{
// contents of mail message
}
using (var server = GetSmtpClient())
{
server.Send(m);
}
但是 server.Send()
正在抛出一个 SmtpException
:
Failure sending mail. ---> System.IO.IOException: Unable to read data from the transport connection: net_io_connectionclosed
我的凭据有问题吗? SMTP 服务器上的 IP 块?也许我的 ISP 阻止了对端口 25 的传出请求?我在与我的调试环境相同的机器上下载并安装了 Thunderbird,并在那里设置了相同的 SMTP 凭据,它运行完美。
为什么它在 Thunderbird 中有效,但在我的代码中却无效?
更新:按照@tzachs的建议,我下载了Wireshark,发现交易进度在一定程度上是相同的。
雷鸟:
TCP 62 25 → 50924 [SYN, ACK] Seq=0 Ack=1 Win=5840 Len=0 MSS=1360 SACK_PERM=1
SMTP 143 S: 220 smtp.somedomain.com ESMTP Sendmail 8.13.8/8.13.8; Sat, 5 Dec 2015 15:46:22 -0500
TCP 54 25 → 50924 [ACK] Seq=90 Ack=18 Win=5840 Len=0
SMTP 289 S: 250 smtp.somedomain.com Hello my-computer.myisp.com [x.x.60.61], pleased to meet you | 250 ENHANCEDSTATUSCODES | 250 PIPELINING | 250 8BITMIME | 250 SIZE | 250 DSN | 250 ETRN | 250 AUTH LOGIN PLAIN | 250 DELIVERBY | 250 HELP
SMTP 82 S: 235 2.0.0 OK Authenticated
etc.
SmtpClient:
TCP 62 25 → 50889 [SYN, ACK] Seq=0 Ack=1 Win=5840 Len=0 MSS=1360 SACK_PERM=1
SMTP 143 S: 220 smtp.somedomain.com ESMTP Sendmail 8.13.8/8.13.8; Sat, 5 Dec 2015 15:45:08 -0500
TCP 54 25 → 50889 [ACK] Seq=90 Ack=21 Win=5840 Len=0
SMTP 289 S: 250 smtp.somedomain.com Hello my-computer.myisp.com [x.x.60.61], pleased to meet you | 250 ENHANCEDSTATUSCODES | 250 PIPELINING | 250 8BITMIME | 250 SIZE | 250 DSN | 250 ETRN | 250 AUTH LOGIN PLAIN | 250 DELIVERBY | 250 HELP
TCP 54 25 → 50889 [FIN, ACK] Seq=325 Ack=62 Win=5840 Len=0
TCP 54 25 → 50889 [ACK] Seq=326 Ack=63 Win=5840 Len=0
请注意,在 SmtpClient 跟踪中的 "pleased to meet you" 行之后,没有任何关于身份验证的内容。不是 "accepted",不是 "failed" - 什么都没有。只是终止连接。
这有什么启示吗?
另一个更新: Smtp 服务器是 运行 SendMail,FWIW。该错误特定于此特定的 Smtp 主机;当我指向不同的服务器时,代码工作正常。
[更新]
将 this 案例与您发布的 Wireshark 事务进行比较,SMTP 服务器关闭了连接。问题是:为什么?也许您的电子邮件有问题。检查您是否填写了发件人、收件人、主题和正文。
希望对您有所帮助。
[旧]
在尝试以编程方式发送消息时,我遇到了类似的情况。
检查您的邮件主机的设置,是否允许每个客户端访问。
另见 so
"Under the "访问安全性较低的应用程序”部分,您可以启用从其他 devices/applications...(例如您的 C# 应用程序)访问您的帐户。”
我还添加了一个 certificat-Call-Back,就像 ukhardy 写的那样。但这只是必要的,如果你 EnableSsl,回调应该做一些验证。
ServicePointManager.ServerCertificateValidationCallback =
delegate(object s, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{ return true; };
smtp.Send(mail);
检查禁用防火墙和防病毒是否有效。
客户端超时默认值是:
client.Timeout = 10000;
另一个用户遇到了由 Program-Structure 引起的相同异常,请参阅 putting client Creation outside loop helped。可能会在静态工厂帮助之外重构客户端生成。
同时检查 DeliveryMethod:
client.DeliveryMethod = SmtpDeliveryMethod.Network;
你试过了吗Mailgun。它将为您发送邮件,并显示电子邮件是从指定的发件人发送的。这是一个非常简单的设置。
您还可以添加电子邮件附件。
只需将其添加到您的网络配置中
Web.config 这将适用于 smtp4dev
<system.net>
<mailSettings>
<smtp>
<network host="localhost" port="25" />
</smtp>
</mailSettings>
</system.net>
Web.Release.config
<system.net>
<mailSettings>
<smtp deliveryMethod="Network" from="noreply@email_you_chose.com" xdt:Transform="Replace">
<network host="smtp.mailgun.org" userName="postmaster@the_address_you_chose.com" password="password the site gives you" />
</smtp>
</mailSettings>
</system.net>
Service.cs
private MailMessage MailMessageFactory(EmailDTO emailDto)
{
var text = emailDto.Body;
var html = emailDto.Body;
var mailMessage = new MailMessage();
foreach (var recipient in emailDto.To)
{
mailMessage.To.Add(new MailAddress(recipient));
}
mailMessage.From = new MailAddress(emailDto.From);
mailMessage.Subject = emailDto.Subject;
mailMessage.Body = emailDto.Body;
mailMessage.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(text, null, MediaTypeNames.Text.Plain));
mailMessage.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(html, null, MediaTypeNames.Text.Html));
mailMessage.IsBodyHtml = true;
return mailMessage;
}
EmailDto.cs
public class EmailDTO
{
public string From { get; set; }
public IList<string> To { get; set; }
public string Subject { get; set; }
public string Body { get; set; }
}
我在使用不同的 SMTP 服务器时确实遇到过一些问题。根据我的经验,默认的 .net smtpclient API 有时不会告诉您真正发生了什么(公平地说,这可能是为我们简化事情的副作用)。 过去对我有帮助的,特别是在故障排除阶段,是使用 .Net SMTP API,它允许我调试它直到 rcpt 命令,并为我提供更丰富的异常信息。
为此,我建议您下载该项目的源代码并调试其 SMTP 示例:MailSystem.Net
有一个名为 ActiveUp.Net.Samples 的 windows 表单项目,只需构建并执行它,您就可以继续进行几分钟。
如果您更喜欢以编程方式使用它,它与 .net smtpclient 非常相似(并且它确实有过载来传递凭据):
ActiveUp.Net.Mail.Message message = new ActiveUp.Net.Mail.Message();
// We assign the sender email
message.From.Email = this.fromEmailTextbox.Text;
// We assign the recipient email
message.To.Add(this.toEmailTextbox.Text);
// We assign the subject
message.Subject = this.subjectTextbox.Text;
// We assign the body text
message.BodyText.Text = this.bodyTextTextbox.Text;
// We send the email using the specified SMTP server
this.AddLogEntry("Sending message.");
try
{
SmtpClient.Send(message, this.smtpServerAddressTextbox.Text);
this.AddLogEntry("Message sent successfully.");
}
catch (SmtpException ex)
{
this.AddLogEntry(string.Format("Smtp Error: {0}", ex.Message));
}
catch (Exception ex)
{
this.AddLogEntry(string.Format("Failed: {0}", ex.Message));
}
希望对您有所帮助。
当我切换到亚马逊电子邮件服务时,我遇到了同样的问题。我以前的电子邮件服务器需要端口,但亚马逊电子邮件服务 运行 不需要。根据您的电子邮件 SMTP 服务器,端口和启用 SSL 设置是必需的。
如果需要,添加端口和 EnableSSL。
public static SmtpClient GetSmtpClient()
{
var client= new SmtpClient();
client.Host= _smtpServer;
client.UseDefaultCredentials = false;
if (smtpUseDefaultCredential)
{
client.UseDefaultCredentials = true;
}
else
{
client.UseDefaultCredentials = false;
client.Credentials = new NetworkCredential(smtpUser, smtpPassword);
}
if(isPortRequired)
{
client.Port= _smtpPort;
}
if(isEnableSslRequired)
{
client.EnableSsl= true;
}
return client;
}
您的 ISP 是否可能实施了 POP before SMTP 之类的功能?我看到您没有在 Thunderbird 对话中发送任何身份验证流量,但我确实记得大约十年前有一个 ISP 使用该机制。
这应该很正常吧?
public static SmtpClient GetSmtpClient()
{
var client = new SmtpClient
{
Host = _smtpServer,
UseDefaultCredentials = false,
Credentials = new NetworkCredential(_smtpUsername, _smtpPassword),
Port = _smtpPort, // port 25
EnableSsl = _smtpSsl // false
};
return client;
}
...
var m = new MailMessage
{
// contents of mail message
}
using (var server = GetSmtpClient())
{
server.Send(m);
}
但是 server.Send()
正在抛出一个 SmtpException
:
Failure sending mail. ---> System.IO.IOException: Unable to read data from the transport connection: net_io_connectionclosed
我的凭据有问题吗? SMTP 服务器上的 IP 块?也许我的 ISP 阻止了对端口 25 的传出请求?我在与我的调试环境相同的机器上下载并安装了 Thunderbird,并在那里设置了相同的 SMTP 凭据,它运行完美。
为什么它在 Thunderbird 中有效,但在我的代码中却无效?
更新:按照@tzachs的建议,我下载了Wireshark,发现交易进度在一定程度上是相同的。
雷鸟:
TCP 62 25 → 50924 [SYN, ACK] Seq=0 Ack=1 Win=5840 Len=0 MSS=1360 SACK_PERM=1
SMTP 143 S: 220 smtp.somedomain.com ESMTP Sendmail 8.13.8/8.13.8; Sat, 5 Dec 2015 15:46:22 -0500
TCP 54 25 → 50924 [ACK] Seq=90 Ack=18 Win=5840 Len=0
SMTP 289 S: 250 smtp.somedomain.com Hello my-computer.myisp.com [x.x.60.61], pleased to meet you | 250 ENHANCEDSTATUSCODES | 250 PIPELINING | 250 8BITMIME | 250 SIZE | 250 DSN | 250 ETRN | 250 AUTH LOGIN PLAIN | 250 DELIVERBY | 250 HELP
SMTP 82 S: 235 2.0.0 OK Authenticated
etc.
SmtpClient:
TCP 62 25 → 50889 [SYN, ACK] Seq=0 Ack=1 Win=5840 Len=0 MSS=1360 SACK_PERM=1
SMTP 143 S: 220 smtp.somedomain.com ESMTP Sendmail 8.13.8/8.13.8; Sat, 5 Dec 2015 15:45:08 -0500
TCP 54 25 → 50889 [ACK] Seq=90 Ack=21 Win=5840 Len=0
SMTP 289 S: 250 smtp.somedomain.com Hello my-computer.myisp.com [x.x.60.61], pleased to meet you | 250 ENHANCEDSTATUSCODES | 250 PIPELINING | 250 8BITMIME | 250 SIZE | 250 DSN | 250 ETRN | 250 AUTH LOGIN PLAIN | 250 DELIVERBY | 250 HELP
TCP 54 25 → 50889 [FIN, ACK] Seq=325 Ack=62 Win=5840 Len=0
TCP 54 25 → 50889 [ACK] Seq=326 Ack=63 Win=5840 Len=0
请注意,在 SmtpClient 跟踪中的 "pleased to meet you" 行之后,没有任何关于身份验证的内容。不是 "accepted",不是 "failed" - 什么都没有。只是终止连接。
这有什么启示吗?
另一个更新: Smtp 服务器是 运行 SendMail,FWIW。该错误特定于此特定的 Smtp 主机;当我指向不同的服务器时,代码工作正常。
[更新] 将 this 案例与您发布的 Wireshark 事务进行比较,SMTP 服务器关闭了连接。问题是:为什么?也许您的电子邮件有问题。检查您是否填写了发件人、收件人、主题和正文。
希望对您有所帮助。
[旧] 在尝试以编程方式发送消息时,我遇到了类似的情况。
检查您的邮件主机的设置,是否允许每个客户端访问。
另见 so
"Under the "访问安全性较低的应用程序”部分,您可以启用从其他 devices/applications...(例如您的 C# 应用程序)访问您的帐户。”
我还添加了一个 certificat-Call-Back,就像 ukhardy 写的那样。但这只是必要的,如果你 EnableSsl,回调应该做一些验证。
ServicePointManager.ServerCertificateValidationCallback =
delegate(object s, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{ return true; };
smtp.Send(mail);
检查禁用防火墙和防病毒是否有效。
客户端超时默认值是:
client.Timeout = 10000;
另一个用户遇到了由 Program-Structure 引起的相同异常,请参阅 putting client Creation outside loop helped。可能会在静态工厂帮助之外重构客户端生成。
同时检查 DeliveryMethod:
client.DeliveryMethod = SmtpDeliveryMethod.Network;
你试过了吗Mailgun。它将为您发送邮件,并显示电子邮件是从指定的发件人发送的。这是一个非常简单的设置。
您还可以添加电子邮件附件。
只需将其添加到您的网络配置中
Web.config 这将适用于 smtp4dev
<system.net>
<mailSettings>
<smtp>
<network host="localhost" port="25" />
</smtp>
</mailSettings>
</system.net>
Web.Release.config
<system.net>
<mailSettings>
<smtp deliveryMethod="Network" from="noreply@email_you_chose.com" xdt:Transform="Replace">
<network host="smtp.mailgun.org" userName="postmaster@the_address_you_chose.com" password="password the site gives you" />
</smtp>
</mailSettings>
</system.net>
Service.cs
private MailMessage MailMessageFactory(EmailDTO emailDto)
{
var text = emailDto.Body;
var html = emailDto.Body;
var mailMessage = new MailMessage();
foreach (var recipient in emailDto.To)
{
mailMessage.To.Add(new MailAddress(recipient));
}
mailMessage.From = new MailAddress(emailDto.From);
mailMessage.Subject = emailDto.Subject;
mailMessage.Body = emailDto.Body;
mailMessage.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(text, null, MediaTypeNames.Text.Plain));
mailMessage.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(html, null, MediaTypeNames.Text.Html));
mailMessage.IsBodyHtml = true;
return mailMessage;
}
EmailDto.cs
public class EmailDTO
{
public string From { get; set; }
public IList<string> To { get; set; }
public string Subject { get; set; }
public string Body { get; set; }
}
我在使用不同的 SMTP 服务器时确实遇到过一些问题。根据我的经验,默认的 .net smtpclient API 有时不会告诉您真正发生了什么(公平地说,这可能是为我们简化事情的副作用)。 过去对我有帮助的,特别是在故障排除阶段,是使用 .Net SMTP API,它允许我调试它直到 rcpt 命令,并为我提供更丰富的异常信息。
为此,我建议您下载该项目的源代码并调试其 SMTP 示例:MailSystem.Net 有一个名为 ActiveUp.Net.Samples 的 windows 表单项目,只需构建并执行它,您就可以继续进行几分钟。
如果您更喜欢以编程方式使用它,它与 .net smtpclient 非常相似(并且它确实有过载来传递凭据):
ActiveUp.Net.Mail.Message message = new ActiveUp.Net.Mail.Message();
// We assign the sender email
message.From.Email = this.fromEmailTextbox.Text;
// We assign the recipient email
message.To.Add(this.toEmailTextbox.Text);
// We assign the subject
message.Subject = this.subjectTextbox.Text;
// We assign the body text
message.BodyText.Text = this.bodyTextTextbox.Text;
// We send the email using the specified SMTP server
this.AddLogEntry("Sending message.");
try
{
SmtpClient.Send(message, this.smtpServerAddressTextbox.Text);
this.AddLogEntry("Message sent successfully.");
}
catch (SmtpException ex)
{
this.AddLogEntry(string.Format("Smtp Error: {0}", ex.Message));
}
catch (Exception ex)
{
this.AddLogEntry(string.Format("Failed: {0}", ex.Message));
}
希望对您有所帮助。
当我切换到亚马逊电子邮件服务时,我遇到了同样的问题。我以前的电子邮件服务器需要端口,但亚马逊电子邮件服务 运行 不需要。根据您的电子邮件 SMTP 服务器,端口和启用 SSL 设置是必需的。 如果需要,添加端口和 EnableSSL。
public static SmtpClient GetSmtpClient()
{
var client= new SmtpClient();
client.Host= _smtpServer;
client.UseDefaultCredentials = false;
if (smtpUseDefaultCredential)
{
client.UseDefaultCredentials = true;
}
else
{
client.UseDefaultCredentials = false;
client.Credentials = new NetworkCredential(smtpUser, smtpPassword);
}
if(isPortRequired)
{
client.Port= _smtpPort;
}
if(isEnableSslRequired)
{
client.EnableSsl= true;
}
return client;
}
您的 ISP 是否可能实施了 POP before SMTP 之类的功能?我看到您没有在 Thunderbird 对话中发送任何身份验证流量,但我确实记得大约十年前有一个 ISP 使用该机制。