SmtpClient可以';t发送;雷鸟可以

本文关键字:发送 雷鸟可 SmtpClient 可以 | 更新日期: 2023-09-27 18:25:42

这应该是很常规的,对吧?

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主机的;当我指向不同的服务器时,代码运行良好。

SmtpClient可以';t发送;雷鸟可以

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

希望能有所帮助。

[update]将此情况与您发布的Wireshark事务进行比较,连接已由SMTP服务器关闭。问题是:为什么?也许你的电子邮件有问题。检查是否填写了"发件人"、"收件人"、"主题"answers"正文"。

希望这能有所帮助。

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

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

也可参见

在"访问不太安全的应用程序"部分,您可以启用从其他设备/应用程序访问您的帐户……如您的C#应用程序

我还添加了一个认证的回拨,就像ukhardy写的那样。但只有当您启用Ssl时,这才是必要的,并且回调应该进行一些验证。

ServicePointManager.ServerCertificateValidationCallback = 
delegate(object s, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) 
{ return true; };
 smtp.Send(mail);

检查禁用防火墙和防病毒功能是否有效

客户端超时默认值为:

client.Timeout = 10000;

另一个用户也有同样的由程序结构引起的异常,请参阅将客户端创建置于循环之外的帮助。可以在静态Factory之外重构客户端生成帮助。

同时检查DeliveryMethod:

client.DeliveryMethod = SmtpDeliveryMethod.Network;

当我切换到亚马逊电子邮件服务时,我也遇到了同样的问题。我以前的电子邮件服务器需要端口,但亚马逊电子邮件服务在没有端口的情况下运行。根据您的电子邮件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在SMTP之前是否已经实现了类似POP的功能?我看到你在Thunderbird对话中没有发送任何身份验证流量,但我确实记得大约十年前有一家ISP使用过这种机制。

您是否尝试过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;
}

电子邮件收件人

public class EmailDTO
{
    public string From { get; set; }
    public IList<string> To { get; set; }
    public string Subject { get; set; }
    public string Body { get; set; }
}