【问题标题】:SmtpClient can't send; Thunderbird canSmtpClient 无法发送;雷鸟可以
【发布时间】:2016-03-09 10:25:24
【问题描述】:

这应该很正常吧?

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

发送邮件失败。 ---> System.IO.IOException: 无法从传输连接中读取数据: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 跟踪中的“很高兴认识您”行之后,没有任何关于身份验证的内容。不是“接受”,也不是“失败”——什么都没有。只是终止连接。

这有什么启示吗?

另一个更新: Smtp 服务器正在运行 SendMail,FWIW。该错误特定于这个特定的 Smtp 主机;当我指向不同的服务器时,代码可以正常工作。

【问题讨论】:

  • 有些服务器要求你在出局前先登录入局服务器,你是不是也在Thunderbird中设置了POP服务器?您确定 SMTP 服务器使用的是非 ssl 端口 25 吗?许多人已经在端口 465 或 587 上迁移到 SSL。
  • 是的,绝对不是 SSL,端口 25。碰巧我在发送邮件之前登录到传入邮件 (POP),但这是使用不同的对象。无论如何,我将如何首先使用 SmtpClient 检查邮件?它只能发送外发邮件。
  • 我会尝试使用wireshark捕获网络通信,它可能会给你一个线索。
  • @tzachs - 使用wireshark 输出更新问题。感谢您的想法!
  • @ShaulBehr 我有一种感觉,wireshark 可能在可扩展行中隐藏了一些额外的信息。您可以尝试 fiddler,并通过:stackoverflow.com/questions/5116148/… 将其配置为 localhost:25 - 并发布您的完整结果吗?确保为请求和响应选择 Raw 选项卡。这会很冗长,但应该能让我们更好地了解正在发生的事情。

标签: c# email smtp sendmail smtpclient


【解决方案1】:

在使用不同的 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));
        }

希望对你有帮助。

【讨论】:

  • 太棒了。 ActiveUp 邮件可与此 Smtp 主机一起使用,而本机 C# SmtpClient 则不能。我不知道我是否会理解为什么,但它足以让你获得赏金。
【解决方案2】:

[更新]this 案例与您发布的 Wireshark 事务进行比较,连接被 SMTP 服务器关闭。问题是:为什么?也许您的电子邮件有问题。检查是否填写了 From、To、Subject 和 Body。

希望这会有所帮助。

[旧] 在尝试以编程方式发送消息时,我遇到了类似的情况。

检查您的邮件主机的设置,如果允许每个客户端访问。

另见so

“在“访问安全性较低的应用程序”部分下,您可以允许从其他设备/应用程序访问您的帐户...例如您的 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;

【讨论】:

  • 与邮件主机的网络管理员交谈。它运行在 Linux 服务器上,没有任何东西可以区分不同的客户端。证书回调什么也不做。
  • 您刚刚添加了超时?默认超时是多少?
  • @ShaulBehr:哦,100000(100 秒)是默认值。所以,这无济于事。
  • @ShaulBehr:设置 client.DeliveryMethod 有帮助吗?
  • 默认为网络。你建议什么设置?
【解决方案3】:

当我切换到亚马逊电子邮件服务时,我遇到了同样的问题。我以前的电子邮件服务器需要端口,但亚马逊电子邮件服务在没有它的情况下运行。根据您的电子邮件 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;
}

【讨论】:

    【解决方案4】:

    您的 ISP 是否有可能实现了 POP before SMTP 之类的功能?我看到您没有在 Thunderbird 对话中发送任何身份验证流量,但我确实记得大约十年前有一个使用该机制的 ISP。

    【讨论】:

      【解决方案5】:

      你试过Mailgun。它将为您发送邮件,并显示电子邮件是从指定的发件人发送的。这是一个非常简单的设置。

      您还可以添加电子邮件附件。

      只需将其添加到您的 webconfig 中

      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; }
      }
      

      【讨论】:

      • 里面有抄送和密件抄送选项,还是每封电子邮件都是为每个人量身定制的?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-04
      • 1970-01-01
      • 2011-03-06
      • 1970-01-01
      • 2014-11-24
      相关资源
      最近更新 更多