【问题标题】:Loop over SmtpClient.Send()循环 SmtpClient.Send()
【发布时间】:2012-02-23 10:26:02
【问题描述】:

我正在开发一个 ASP.NET (C#) 产品,该产品必须向订阅者列表发送独特的电子邮件。我的代码如下所示:

// Grab subscribers from db, about 10-20.
var malingList = Bll.GetAllSubscribers();
var client = new SmtpClient(); 
 
// Set up settings on the SmtpClient with cridentails and so on

foreach(var subscriber in mailingList)
{
  var message = new MailMessage(); 
  // Set up message, set reciver, yada yada
  client.Send(message);
}

client.Dispose();

我在使用“假 smtp”剪纸进行测试时收到此错误:发送邮件失败。无法将数据写入传输连接:

我想要做的是保持 SMTP 连接也打开。不必在每封电子邮件中重复“握手”。

我不确定 100 但是。这应该工作吗?我想我还有另一个项目是这样实现的。

【问题讨论】:

  • Client.Send(message); 应该是client.Send(message);
  • 您不使用Using (var client = new SmtpClient())的任何原因?
  • @James Hill - 是的,这只是为了展示这个概念。 @ Erik Philips - 你读过这篇文章吗?在 using 语句中包装这些行将在每次发送时调用 Dispose。我不想在每次查看时都发送 QUIT 命令。如果可能的话,我想保持连接并在 10-20 次发送中重复使用它。另一方面,我可以将 foreach 包装在 using 语句中。无论如何,这不是问题。

标签: c# asp.net email smtpclient


【解决方案1】:

Papercut 库将无法促进您正在寻找的行为,因为每次您调用 Send 时,它都会断开当前连接并建立与服务器的另一个连接并进行握手。以下是他们的 CodePlex 存储库的源代码:

public void Send()
{
    string response;

    Connect(session.Sender, 25);
    response = Response();
    if (response.Substring(0, 3) != "220")
        throw new SmtpException(response);

    Write("HELO {0}\r\n", Util.GetIPAddress());
    response = Response();
    if (response.Substring(0, 3) != "250")
        throw new SmtpException(response);

    Write("MAIL FROM:<{0}>\r\n", session.MailFrom);
    response = Response();
    if (response.Substring(0, 3) != "250")
        throw new SmtpException(response);

    session.Recipients.ForEach(address =>
        {
            Write("RCPT TO:<{0}>\r\n", address);
            response = Response();
            if (response.Substring(0, 3) != "250")
                throw new SmtpException(response);
        });

    Write("DATA\r\n");
    response = Response();
    if (response.Substring(0, 3) != "354")
        throw new SmtpException(response);

    NetworkStream stream = GetStream();
    stream.Write(session.Message, 0, session.Message.Length);

    Write("\r\n.\r\n");
    response = Response();
    if (response.Substring(0, 3) != "250")
        throw new SmtpException(response);

    Write("QUIT\r\n");
    response = Response();
    if (response.IndexOf("221") == -1)
        throw new SmtpException(response);
}

在考虑到它是开源之后,您当然可以更改源代码以做您想做的事情。

【讨论】:

  • 但我使用剪纸作为 Smtp 服务器进行测试。对于发送,我使用的是 asp.web.mail-classes。会不会是服务器终止了连接?
  • 这将是包含在您的问题中的好信息(Papercut 还包括一个名为 SmtpClient 的 SMTP 客户端库,我认为您的问题与此有关)。有了这些信息,我会尝试重新分析您的问题。
  • 这简直太痛苦了。他们对 SMTP 的实现与我过去使用的不同,到我认为它不符合标准的程度。如果您正在寻找一种简单的方法来测试发送电子邮件的程序,那么只需在 Gmail、Live 等网站上开设一个免费帐户。它会为您节省大量时间。
  • 我刚刚检查了 System.Net.Mail.SmtpClient 类在内部做了什么,它也没有在其生命周期内保持持久连接,所以它也不会允许你尝试做的事情。跨度>
  • 感谢您的帮助!只是为了保护我自己,我确实在问题 =D 中写了“as fake smtp”。所以你的意思是我应该在测试时跳过 Pupercut-smtp 服务器?我想对此进行测试并“捕获”本地服务器上的电子邮件。
【解决方案2】:

我想这可能与 smtp 客户端发送批量邮件的限制有关。 也许您可以在 20 到 30 封邮件之后不时处置客户?

答案来自: Failure sending mail. Unable to write data to the transport connection

【讨论】:

  • 这就是我现在正在做的事情,但这个错误仅在 1-2 条消息后显示。我怀疑这可能与 Papercut 软件或其对 smtp 协议的实现有关。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-08
  • 1970-01-01
  • 2015-12-20
  • 2014-05-07
相关资源
最近更新 更多