繁体   English   中英

MailKit - SmtpClient Connect方法冻结

[英]MailKit - SmtpClient Connect method freezes

我正在开发一个Xamarin安卓应用程序,在某些时候(成功交易后)应用程序必须向客户发送信息电子邮件。 创建MimeMessage实例以及实际发送它的整个过程都是通过任务完成的。 消息(大多数时候包含链接的图像)是完美创建的,但是当我调用一个方法来实际发送它时,执行会在该调用时冻结并且整个任务保持活动状态但在此时冻结。

这是我的SendMail方法,除MimeMessage参数外,还接收MailAccount类,其中包含有关smtp机器,端口和发件人帐户的信息。 一旦调用MailKit的SmtpClient实例的Connect方法,我就会遇到我描述的“冻结”行为。 我尝试了很多次 - 甚至一旦代码继续超出那条线。

private static int SendMail(MailAccount account, MimeMessage message)
{
    using (var client = new SmtpClient())
    {
        try
        {
            client.Connect(account.Server, account.Port, false);
        }
        catch (SmtpCommandException)
        {
            return -1;
        }
        catch (SmtpProtocolException)
        {
            return -2;
        }

        client.AuthenticationMechanisms.Remove("XOAUTH2");

        if (client.Capabilities.HasFlag(SmtpCapabilities.Authentication))
        {
            try
            {
                client.Authenticate(account.User, Decrypt(account.Pass));
            }
            catch (AuthenticationException)
            {
                return -3;
            }
            catch (SmtpCommandException)
            {
                return -1;
            }
            catch (SmtpProtocolException)
            {
                return -2;
            }
        }

        int status = 1; //assume success

        try
        {
            client.Send(message);
        }
        catch (SmtpCommandException ex)
        {
            switch (ex.ErrorCode)
            {
                case SmtpErrorCode.MessageNotAccepted:
                    status = -6;
                    break;

                case SmtpErrorCode.SenderNotAccepted:
                    status = -5;
                    break;

                case SmtpErrorCode.RecipientNotAccepted:
                    status = -4;
                    break;

                default:
                    status = -7;
                    break;
            }
        }

        client.Disconnect(true);
        return status;
    }
}

通常,在调用client.Connect挂起会建议您尝试连接的主机或端口不可用。 检查主机和端口是否正确。

如果它们正确的,请确保您使用的是最新版本的MailKit,因为某些旧版本使用Socket.BeginConnect (string, int ...) ,在启用IPv6的操作系统上,有时会尝试使用IPv4 over IPv6并挂起在某些情况下(例如使用像Avast这样的病毒扫描程序时)。

较新版本的MailKit(> = 2.1.4和2.0之前的版本)执行远程主机的DNS查找,并手动指定在实例化Socket(IPv4与IPv6)时使用的正确地址系列,以避免此问题。

挂起也可能是由无响应的证书颁发机构进行SSL / TLS证书吊销检查引起的。 您可以使用以下代码段禁用证书吊销检查:

client.CheckCertificateRevocation = false;

只需确保在调用Connect 之前设置该属性。

通过在Visual Studio中创建新的控制台应用程序并粘贴以下代码并检查其是否有效,可能值得测试对SMTP服务器的访问:

using System;
using System.Threading;
using System.Threading.Tasks;

using MailKit;
using MailKit.Net.Smtp;

namespace ConsoleApp {
    public class Program
    {
        static void Main (string[] args)
        {
            using (var client = new SmtpClient (new ProtocolLogger ("smtp.log"))) {
                using (var cts = new CancellationTokenSource (60000)) {
                    try {
                        client.Connect ("your-host.com", 25, false, cts.Token);
                        client.Disconnect (true);
                    } catch (Exception ex) {
                        Console.WriteLine ("Error connecting: {0}", ex.Message);
                        Console.WriteLine (ex.StackTrace);
                    }
                }
            }
        }
    }
}

了解您的Android应用程序是否在端口465useSsl = true )上连接到smtp.gmail.com时出现问题也很有趣。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM