【问题标题】:SmtpClient.Send gets stuckSmtpClient.Send 卡住
【发布时间】:2018-12-22 00:29:02
【问题描述】:
string host = "gauntlet.asoshared.com", username= "a@a.test", pwd = "abc",
    from = "a@a.test", to = "b@b.test";
int port = 465;

var mm = new MailMessage(from, to);
mm.Body = "b1";
mm.Subject = "s1";
mm.IsBodyHtml=false;
using (var smtp=new SmtpClient(host, port)) {
    smtp.EnableSsl = true;
    smtp.Credentials = new NetworkCredential (username, pwd);
    smtp.Send(mm);
}

这一直停留在smtp.Send。大约 2 分钟后,我收到超时错误。使用 Outlook,它可以完美运行(使用我的真实凭据)。 查看 Wireshark,我在运行此代码时看到 TCP SYN、SYN-ACK、ACK,然后什么也没有。使用 Outlook 时,这些后面跟着 TLSv1.2 Client Hello 等。

尝试在代码开头添加以下行:

ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
ServicePointManager.Expect100Continue=false;

为什么 C# 卡住了,甚至没有发送 Client Hello

当我使用不同的主机时它工作正常。

编辑:您可以通过按原样运行上面的代码自行重现该问题。您将收到超时错误而不是凭据错误错误,并且使用 wireshark,您可以看到 C# 甚至没有尝试 TLS 连接。

【问题讨论】:

  • 你的代码没有问题。输入主机/凭据信息后,对我来说效果很好。如果您有权访问 smtp 服务器,您可能需要检查它的日志。
  • @just-my-name 您是否使用我发布的主机和凭据按原样尝试了我的代码?为什么它会卡住而不是给出错误的凭据错误?如果您查看 wireshark,您会发现 C# 甚至没有尝试启动 TLS 连接。
  • 是的,我做到了,它的行为与您描述的一样。然后我用我的主机替换它,它工作得很好。这就是为什么我怀疑它与您的 smtp 服务器有关。
  • @just-my-name 这不是我的 SMTP 服务器,而是 A Small Orange 的。此外,您还没有解释为什么 Outlook 可以正常发送,而 C# 会阻塞。

标签: c# smtp


【解决方案1】:

我认为问题在于隐式 SSL。

System.Net.Mail 仅支持“显式”SSL,如下所述:

http://blogs.msdn.com/webdav_101/archive/2008/06/02/system-net-mail-with-ssl-to-authenticate-against-port-465.aspx

通常这是由约定管理的。在端口 25(正常情况)上运行的 SMTP 使用显式 SSL。在端口 465 上运行的 SMTPS 使用隐式 SSL。在端口 587 上运行的邮件提交使用显式 SSL。

如果允许显式 SSL,您可以尝试端口 25

【讨论】:

【解决方案2】:

这可能是题外话,但我想建议你使用

https://github.com/jstedfast/MailKit

不要自己创建 smtp 客户端,这是来自https://www.infoq.com/news/2017/04/MailKit-MimeKit-Official 的原因。

SmtpClient 的主要问题是它的连接生命周期很混乱。连接到 SMTP 服务器可能会很耗时,尤其是在启用身份验证的情况下,因此每个 SmtpClient 对象都有一个内部连接池。

【讨论】:

    【解决方案3】:

    试试下面的代码。

    private async Task<bool> SendEmail(string Email, string Message)
        {
            try
            {
                SmtpClient client = new SmtpClient("www.test.com");
                    client.UseDefaultCredentials = false;
                    client.Credentials = new NetworkCredential("abc@test.com", "password");
                MailMessage mailMessage = new MailMessage();
                mailMessage.From = new MailAddress("test@from.com");
                mailMessage.To.Add(Email);
                mailMessage.Body = Message;
                mailMessage.Subject = "abc";
                await client.SendMailAsync(mailMessage);
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
    
        }
    

    【讨论】:

      【解决方案4】:

      这段代码对我有用

      SmtpClient client = new SmtpClient('smtp.domain.com',25);
          client.DeliveryMethod = SmtpDeliveryMethod.Network;
          client.UseDefaultCredentials = true;
          client.Credentials = new NetworkCredential('username', 'password');
          client.EnableSsl = false;
          client.Send(mm);
      

      您可以尝试添加 client.DeliveryMethod

      【讨论】:

      • 谢谢,但这没有帮助。
      猜你喜欢
      • 2012-02-23
      • 1970-01-01
      • 2013-02-26
      • 2017-12-29
      • 2011-08-04
      • 2011-11-17
      • 2014-03-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多