【问题标题】:"existing connection was forcibly closed" error on sending email in .NET 2.0在 .NET 2.0 中发送电子邮件时出现“现有连接被强制关闭”错误
【发布时间】:2011-12-20 19:53:50
【问题描述】:

我有 asp.net 网站。我正在通过SMTPClient 发送电子邮件。我不时收到此错误:

 InnerException = System.IO.IOException: Unable to read data from the transport connection: 
    An existing connection was forcibly closed by the remote host. ---> 
       System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
   at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
   at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
   --- End of inner exception stack trace ---
   at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
   at System.Net.DelegatedStream.Read(Byte[] buffer, Int32 offset, Int32 count)
   at System.Net.BufferedReadStream.Read(Byte[] buffer, Int32 offset, Int32 count)
   at System.Net.Mail.SmtpReplyReaderFactory.ReadLines(SmtpReplyReader caller, Boolean oneLine)
   at System.Net.Mail.SmtpReplyReaderFactory.ReadLine(SmtpReplyReader caller)
   at System.Net.Mail.SmtpReplyReader.ReadLine()
   at System.Net.Mail.CheckCommand.Send(SmtpConnection conn, String& response)
   at System.Net.Mail.DataStopCommand.Send(SmtpConnection conn)
   at System.Net.Mail.SmtpConnection.OnClose(Object sender, EventArgs args)
   at System.Net.ClosableStream.Close()
   at System.Net.Mail.MailWriter.Close()
   at System.Net.Mail.SmtpClient.Send(MailMessage message).

代码:

 SmtpClient smtpClient = new SmtpClient(ConfigurationManager.AppSettings["smtpserverwwwpo"]);
    try
    {
        NetworkCredential basicCredential =
            new NetworkCredential(ConfigurationManager.AppSettings["smtp_user_name"], ConfigurationManager.AppSettings["smtp_password"]);
        smtpClient.UseDefaultCredentials = false;
        smtpClient.Credentials = basicCredential;
    }
    catch
    {
        smtpClient.UseDefaultCredentials = true;
    }

    System.Net.Mail.MailMessage msg = new System.Net.Mail.MailMessage();
    msg.Subject = subject;
    msg.To.Add(new MailAddress(someEmail));
    msg.From = new MailAddress(ConfigurationManager.AppSettings["from_email_address"]);
    msg.Headers.Add("Content-Type", "text/html");
    msg.BodyEncoding = System.Text.Encoding.UTF8;

try{
        smtpClient.Send(msg);
} 
catch(Exception ex)
{
 //write log 
}

}

什么原因会导致呢?

【问题讨论】:

  • 看起来 SMTP 服务器关闭了连接。也许检查服务器的日志?
  • 您是使用套接字还是使用 smtp / System.Net.Mail 发送电子邮件?您有什么代码请发布.. 通过 .NET 发送电子邮件相当简单直接
  • 您可能被远程主机上的垃圾邮件预防机制踢了。您生成电子邮件的速度有多快?您要发送到哪种邮件服务器(Exchange、sendmail 等)?
  • 您可以通过配置文件中的 system.net.mail 而不是 appsettings 配置 SmtpClient 来清理大部分代码。这对您的问题没有任何影响,但会使代码更清晰。
  • 我也看到了这个,关键短语(从我的角度来看)是“不时”。周五,一名应用用户经历了 24 次发起电子邮件的过程,其中 3 次失败。我习惯于击球 1.000,但 0.875 已经足够好,我自己的代码似乎得到了肯定。 (这开始于几个月前,在 .NET 2.0 上,我已将应用程序更新到 .NET 3.5,但交易相同。)

标签: c# asp.net windows sendmail smtpclient


【解决方案1】:

MailMessage 是一次性的。您可以尝试将其包装在 using 语句中。

using(var message = new MailMessage {Subject ="...", Body="..."})
{
   message.To.Add("email address");
   new SmtpClient().Send(message)
}

【讨论】:

    【解决方案2】:

    我相信这与您发布的实际代码几乎没有关系,而与您所连接的服务器所解释的请求的数量和内容有关。强行关闭连接是一种故意行为,而不是随机错误,这意味着服务器选择这样做是基于满足某些条件。

    正如上面所建议的,也许你正在达到一些你不知道的极限;或者,远程服务器可能特别忙并关闭了连接(并且没有针对这种情况返回正确的错误代码)。

    【讨论】:

      【解决方案3】:

      也许您应该将 SmtpClient.EnableSsl 设置为 false。

      【讨论】:

        【解决方案4】:

        您在哪里分配 SMTP 客户端的主机名...?

        如果您将代码更改为使用以下内容会怎样

        System.Net.Mail.MailMessage message = new System.Net.Mail.MailMessage();
        message.To.Add("youremailAddress");
        message.Subject = "This is the Subject line";
        message.From = new System.Net.Mail.MailAddress("From@online.microsoft.com");
        message.Body = "This is the message body";
        System.Net.Mail.SmtpClient smtp = new System.Net.Mail.SmtpClient("yoursmtphost");
        smtp.Send(message);
        

        【讨论】:

        • 应用程序正在生产中。并且需要设置凭证。
        • 好的,这意味着如果您不是有效的网络用户或没有有效的系统帐户,那么如果尝试发送电子邮件将失败..?仍然可以使用相同的代码示例。我可能错了,但是当您需要做的只是在 Add() 部分中传递电子邮件地址时,为什么还要添加新的 MailAddress ......?
        【解决方案5】:

        SMTPClient 类实现 IDisposable 接口。 每当 Type 实现 IDisposable 时,您应该使用 Using(){} 语句。

        例如-

        using (SmtpClient SmtpServer = new SmtpClient(smtpConfig.SmtpMailServer))
                            {
                               //your code
                            }
        

        【讨论】:

          猜你喜欢
          • 2014-12-02
          • 1970-01-01
          • 2013-11-24
          • 2014-11-07
          • 2010-11-12
          • 2017-05-03
          • 1970-01-01
          • 2015-03-08
          • 2014-06-07
          相关资源
          最近更新 更多