所有端口上通过 C# .Net 的 GMail SMTP 错误

Posted

技术标签:

【中文标题】所有端口上通过 C# .Net 的 GMail SMTP 错误【英文标题】:GMail SMTP via C# .Net errors on all ports 【发布时间】:2010-11-08 02:35:09 【问题描述】:

我一直在尝试解决这个问题,但到目前为止一直失败得很惨。我最近的尝试是从这里的堆栈代码中提取的:Sending email through Gmail SMTP server with C#,但我已经尝试了在堆栈和其他地方可以找到的所有语法。我目前的代码是:

var client = new SmtpClient("smtp.gmail.com", 587)

    Credentials = new NetworkCredential("me@gmail.com", "mypass"),
    EnableSsl = true
;

client.Send("me@gmail.com","me@gmail.com","Test", "test message");

运行该代码会给我一个即时异常“发送邮件失败”,其中包含“无法连接到远程服务器”的内部解释。

如果我将端口更改为 465(正如 gmail 文档所建议的那样),我每次都会超时。

我听说 465 不是一个好用的端口,所以我想知道与 587 的交易是什么让我无法连接。我的用户和通行证是正确的。我读到我必须在我的 gmail 帐户上设置 POP 服务,所以我这样做了。没用。

我最初试图让这个为我的品牌 GMail 帐户工作,但在遇到相同的问题之后,我认为使用我的常规 gmail 帐户会更容易......所以远非如此。

【问题讨论】:

您可以通过标准电子邮件客户端进行连接吗?如果没有,可能是你的防火墙有问题。您是否在您的帐户中启用了 POP 访问? 【参考方案1】:

我尝试了你的代码,它在端口 587 上运行良好,但在 465 上却不行。

你检查过防火墙吗?从命令行尝试“Telnet smtp.gmail.com 587” 如果您返回“220 mx.google.com ESMTP....”,则端口已打开。如果不是,它会阻止你调用。

丹尼尔

【讨论】:

谢谢,就是这样。我在防火墙中设置了允许端口 587 通过的规则,并且我的电子邮件客户端使用它没有问题,但我的 a/v 对我的控制台测试应用程序持怀疑态度,认为它是试图传播的蠕虫。 你好,我在 telnet 中尝试了这个测试,它有效(我有 220 mx.google.com ESMTP),但是当我尝试使用 .net 2.0 应用程序发送邮件时,我得到 Server does not support secure connections. 你呢知道是什么导致了问题 @Paul 有人可以看看这里吗? ***.com/questions/52386437/…【参考方案2】:

我在某个时候实现了一个电子邮件客户端,它可以在 587 和 465 上与 gmail 通信...

端口 25 是普通的未加密弹出端口;在 gmail 上不可用。

另外两个端口有加密; 587 使用 TLS,465 使用 SSL。

要使用 587,您应该设置 SmtpClient.EnableSsl = true。

465 不能与 SmtpClient 一起使用,它将与已弃用的类 SmtpMail 一起使用。

【讨论】:

【参考方案3】:

您的专用网络的防火墙阻止了端口 587 和 465。您可以使用默认端口 25 或启用防火墙上的端口

【讨论】:

【参考方案4】:

我不久前也遇到过这个问题。问题是 SmtpClient 不支持隐式 SSL 连接,但支持显式连接 (System.Net.Mail with SSL to authenticate against port 465)。以前的 MailMessage 类(我相信 .Net 1.0)确实支持这一点,但早已过时了。

我的回答是直接通过 COM 调用 CDO(协作数据对象)(http://support.microsoft.com/kb/310212),使用类似以下内容:

    /// <summary>
    /// Send an electronic message using the Collaboration Data Objects (CDO).
    /// </summary>
    /// <remarks>http://support.microsoft.com/kb/310212</remarks>
    private void SendTestCDOMessage()
    
        try
        
            string yourEmail = "YourUserName@gmail.com";

            CDO.Message message = new CDO.Message();
            CDO.IConfiguration configuration = message.Configuration;
            ADODB.Fields fields = configuration.Fields;

            Console.WriteLine(String.Format("Configuring CDO settings..."));

            // Set configuration.
            // sendusing:               cdoSendUsingPort, value 2, for sending the message using the network.
            // smtpauthenticate:     Specifies the mechanism used when authenticating to an SMTP service over the network.
            //                                  Possible values are:
            //                                  - cdoAnonymous, value 0. Do not authenticate.
            //                                  - cdoBasic, value 1. Use basic clear-text authentication. (Hint: This requires the use of "sendusername" and "sendpassword" fields)
            //                                  - cdoNTLM, value 2. The current process security context is used to authenticate with the service.

            ADODB.Field field = fields["http://schemas.microsoft.com/cdo/configuration/smtpserver"];
            field.Value = "smtp.gmail.com";

            field = fields["http://schemas.microsoft.com/cdo/configuration/smtpserverport"];
            field.Value = 465;

            field = fields["http://schemas.microsoft.com/cdo/configuration/sendusing"];
            field.Value = CDO.CdoSendUsing.cdoSendUsingPort;

            field = fields["http://schemas.microsoft.com/cdo/configuration/smtpauthenticate"];
            field.Value = CDO.CdoProtocolsAuthentication.cdoBasic;

            field = fields["http://schemas.microsoft.com/cdo/configuration/sendusername"];
            field.Value = yourEmail;

            field = fields["http://schemas.microsoft.com/cdo/configuration/sendpassword"];
            field.Value = "YourPassword";

            field = fields["http://schemas.microsoft.com/cdo/configuration/smtpusessl"];
            field.Value = "true";

            fields.Update();

            Console.WriteLine(String.Format("Building CDO Message..."));

            message.From = yourEmail;
            message.To = yourEmail;
            message.Subject = "Test message.";
            message.TextBody = "This is a test message. Please disregard.";

            Console.WriteLine(String.Format("Attempting to connect to remote server..."));

            // Send message.
            message.Send();

            Console.WriteLine("Message sent.");
        
        catch (Exception ex)
        
            Console.WriteLine(ex.Message);
        
    

不要忘记浏览您的 COM 引用并添加“Microsoft CDO for Windows 200 Library”,它应该添加两个引用:ADODB 和 CDO。

【讨论】:

【参考方案5】:

我遇到了同样的问题,但我无权更改我公司的防火墙限制。根据this Google doc 上的注释之一,以及上面erdenetsogt 的回答,我尝试使用端口25 并且它有效。 (起初我担心使用端口 25 可能意味着该消息可能未加密;所以我将 EnableSSL 设置为 false,这导致 gmail 拒绝它,因为从未调用过 StartTLS。这使我相信 gmail 正在执行 Explicit SSL,甚至通过端口 25)。

【讨论】:

【参考方案6】:

在服务器上试试这个链接http://www.google.com/accounts/DisplayUnlockCaptcha。

企业 Gmail 帐户(或不确定的普通 gmail 帐户)第一次需要 DisplayUnlockCaptcha。

【讨论】:

【参考方案7】:

通过 SSL 执行 SMTP 有两种方法:显式和隐式。显式意味着你以明文连接到一个普通的 SMTP 端口(通常是 25 或 587),然后发出“starttls”命令来切换到 SSL 模式。隐式意味着您连接到一个期望所有内容都是 SSL 的端口(通常是 465)。

Asp.net 使用“System.Net.Mail.SmtpClient()”发送电子邮件。主要问题是 SmtpClient 不支持隐式 SSL 连接,但支持显式连接(使用 SSL 的 System.Net.Mail 对端口 465 进行身份验证)。因此,如果邮件服务器(SMTP)不支持显式连接,则无法发送电子邮件并显示“连接超时”、“无法将消息发送到 SMTP 服务器。传输错误代码为 0x80040217。服务器响应不可用”等。

为了在 ASP.net 中解决这个问题,我们可以使用 Windows 2000 库 (Cdosys.dll) 的协作数据对象 (CDO) 来发送带有附件的电子邮件消息。 Microsoft Outlook 使用此 DLL 发送电子邮件。在您的 ASP.net 解决方案中,您必须添加参考“Microsoft CDO for windows 2000 Library”。它将在 Bin 文件夹中添加两个标记的 dll。

现在在 C#.net 中执行以下代码:

public static void SendMail(string FromName, string FromEmail, string ReceiverEmail, string CC, string BCC, string subj, string Mssg)

 const var cdoSendUsingPort = 2;
 const var cdoBasicAuth = 1;
 const var cdoTimeout = 60;
 var mailServer = "mail.XXXXXXX.net";
 var SMTPport = 465;
 var mailusername = "yyy@XXXXXXX.net";
 var mailpassword = "PPPPXXXX";
 var objEmail = CreateObject("CDO.Message");
 var objConf = objEmail.Configuration;
 var objFlds = objConf.Fields;
 objFlds.Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = cdoSendUsingPort;
 objFlds.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = mailServer;
 objFlds.Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = SMTPport;
 objFlds.Item("http://schemas.microsoft.com/cdo/configuration/smtpusessl") = true;
 objFlds.Item("http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout") = cdoTimeout;
 objFlds.Item("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = cdoBasicAuth;
 objFlds.Item("http://schemas.microsoft.com/cdo/configuration/sendusername") = mailusername;
 objFlds.Item("http://schemas.microsoft.com/cdo/configuration/sendpassword") = mailpassword;
 objFlds.Update();
 objEmail.To = ReceiverEmail;
 objEmail.From = FromEmail;
 objEmail.CC = CC;
 objEmail.BCC = BCC;
 objEmail.Subject = subj;
 objEmail.htmlBody = Mssg;
 objEmail.Send();

在 VB.net 中

Public Shared Sub SendMail(ByVal FromName As String, ByVal FromEmail As String, ByVal ReceiverEmail As String, ByVal CC As String, ByVal BCC As String, ByVal subj As String, ByVal Mssg As String)

''#################Sending Email##########################

Const cdoSendUsingPort = 2 ' Send the message using SMTP
 Const cdoBasicAuth = 1 ' Clear-text authentication
 Const cdoTimeout = 60 ' Timeout for SMTP in seconds

Dim mailServer = "mail.XXXXXXX.net"
 Dim SMTPport = 465
 Dim mailusername = "yyy@XXXXXXX.net"
 Dim mailpassword = "PPPPXXXX"




Dim objEmail = CreateObject("CDO.Message")
 Dim objConf = objEmail.Configuration
 Dim objFlds = objConf.Fields

With objFlds
 .Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = cdoSendUsingPort
 .Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = mailServer
 .Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = SMTPport
 .Item("http://schemas.microsoft.com/cdo/configuration/smtpusessl") = True
 .Item("http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout") = cdoTimeout
 .Item("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = cdoBasicAuth
 .Item("http://schemas.microsoft.com/cdo/configuration/sendusername") = mailusername
 .Item("http://schemas.microsoft.com/cdo/configuration/sendpassword") = mailpassword
 .Update()
 End With

objEmail.To = ReceiverEmail
 objEmail.From = FromEmail
 objEmail.CC = CC
 objEmail.BCC = BCC
 objEmail.Subject = subj
 objEmail.HTMLBody = Mssg
 'objEmail.AddAttachment "C:\report.pdf"
 objEmail.Send()
 End Sub

参考: Original post 隐式和显式 SMTP http://help.fogcreek.com/9002/using-an-smtp-server-with-ssl 使用 Cdosys.dll 库发送带有附件https://support.microsoft.com/en-us/help/310212/how-to-use-the-cdosys-dll-library-to-send-an-e-mail-message-with-attac的电子邮件

【讨论】:

以上是关于所有端口上通过 C# .Net 的 GMail SMTP 错误的主要内容,如果未能解决你的问题,请参考以下文章

使用 c# .net 库检查来自 gmail 服务器的 IMAP 消息 [关闭]

如何通过 Gmail 使用 C# 发送电子邮件

通过 GoDaddy 上的 gmail SMTP 发送电子邮件 [关闭]

通过 C# 发送 Gmail [重复]

在 C# 中使用 AE.Net.Mail 访问 GMail

C#如何将网页绑定到本地的某个端口上