使用 SMTP 时“尝试以访问权限禁止的方式访问套接字”

Posted

技术标签:

【中文标题】使用 SMTP 时“尝试以访问权限禁止的方式访问套接字”【英文标题】:"An attempt was made to access a socket in a way forbidden by its access permissions" while using SMTP 【发布时间】:2013-12-26 04:55:25 【问题描述】:

当数据库中的某些值超过其阈值时,我正在尝试发送 SMTP 电子邮件。

我已经在 Windows 防火墙中允许了端口 25,587 和 465,并在防病毒软件中禁用了阻止群发邮件的选项。我正在使用的代码如下所示

using System.Net;
using System.Net.Mail;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;

 MailMessage mailMsg = new MailMessage();
        mailMsg.To.Add("to@domain.com");
        // From
        MailAddress mailAddress = new MailAddress("from@domain.com");
        mailMsg.From = mailAddress;


        // Subject and Body
        mailMsg.Subject = "MCAS Alert";
        mailMsg.Body = "Parameter out of range";


        SmtpClient smtpClient = new SmtpClient("smtp.servername.com", 25);
        smtpClient.UseDefaultCredentials = false;
        smtpClient.Timeout = 30000;
        System.Net.NetworkCredential credentials =
           new System.Net.NetworkCredential("username", "passwrod");
        smtpClient.Credentials = credentials;
        smtpClient.EnableSsl = true;
        //ServicePointManager.ServerCertificateValidationCallback = delegate(object s, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)  return true; ;
        smtpClient.Send(mailMsg);

堆栈跟踪

[SocketException (0x271d): An attempt was made to access a socket in a way forbidden by its access permissions xx.xx.xx.xx:25]
   System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress) +208
   System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure, Socket s4, Socket s6, Socket& socket, IPAddress& address, ConnectSocketState state, IAsyncResult asyncResult, Exception& exception) +464

[WebException: Unable to connect to the remote server]
   System.Net.ServicePoint.GetConnection(PooledStream PooledStream, Object owner, Boolean async, IPAddress& address, Socket& abortSocket, Socket& abortSocket6) +6486360
   System.Net.PooledStream.Activate(Object owningObject, Boolean async, GeneralAsyncDelegate asyncCallback) +307
   System.Net.PooledStream.Activate(Object owningObject, GeneralAsyncDelegate asyncCallback) +19
   System.Net.ConnectionPool.GetConnection(Object owningObject, GeneralAsyncDelegate asyncCallback, Int32 creationTimeout) +324
   System.Net.Mail.SmtpConnection.GetConnection(ServicePoint servicePoint) +141
   System.Net.Mail.SmtpTransport.GetConnection(ServicePoint servicePoint) +170
   System.Net.Mail.SmtpClient.GetConnection() +44
   System.Net.Mail.SmtpClient.Send(MailMessage message) +1554

[SmtpException: Failure sending mail.]
   System.Net.Mail.SmtpClient.Send(MailMessage message) +1906
   Admin_Alert.SMTPAuth() in c:\Users\spandya\Documents\Visual Studio 2012\WebSites\WebSite3\Admin\Alert.aspx.cs:61
   Admin_Alert.Page_Load(Object sender, EventArgs e) in c:\Users\spandya\Documents\Visual Studio 2012\WebSites\WebSite3\Admin\Alert.aspx.cs:22
   System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +51
   System.Web.UI.Control.OnLoad(EventArgs e) +92
   System.Web.UI.Control.LoadRecursive() +54
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +772

我在这里还缺少什么?这些特定的端口地址有防火墙入站规则。

【问题讨论】:

错误来自发送方还是接收方? 检查堆栈跟踪的编辑 您是否尝试过从相关机器 Telnet 到此端口以确保路由打开?类似telnet smtp.mydomain.com 25 主要是SocketException (0x271d) 被抛出用于端口块,所以您可以检查该服务器上的netstat -anb | find "25" 或远程检查telnet smtp.servername.com 25 以检查该端口是否在您的smtp 服务器上打开? 我尝试了telnet,但它说无法连接到端口25上的主机 【参考方案1】:

请确认您的防火墙允许出站流量,并且您没有被防病毒软件阻止。

我收到了同样的问题,罪魁祸首是防病毒软件。

【讨论】:

我已允许端口 25 用于 Windows 防火墙的入站和出站。 我禁用了防病毒和防火墙。 异常的StackTrace变了吗?【参考方案2】:

好的,了解这里的含义非常重要。

文档说 SmtpClient 不支持超过 465 的 SSL。

似乎您别无选择,只能使用您的邮件主机可能不支持的 STARTTLS。如果您的主机需要使用超过 465 的 SSL,您可能必须使用不同的库。

引自http://msdn.microsoft.com/en-us/library/system.net.mail.smtpclient.enablessl(v=vs.110).aspx

SmtpClient 类仅支持 RFC 3207 中定义的基于传输层安全的安全 SMTP 的 SMTP 服务扩展。在这种模式下,SMTP 会话在未加密的通道上开始,然后客户端向服务器发出 STARTTLS 命令切换到使用 SSL 的安全通信。有关详细信息,请参阅 Internet 工程任务组 (IETF) 发布的 RFC 3207。

另一种连接方法是在发送任何协议命令之前预先建立 SSL 会话。这种连接方法有时称为 SMTP/SSL、SMTP over SSL 或 SMTPS,默认使用端口 465。目前不支持这种使用 SSL 的替代连接方法。

【讨论】:

嗯,我的目标端口是 25。我正在尝试使用 Outlook 中的电子邮件而不是 gmail 发送邮件。 @SPandya 您不能使用 Outlook“发送邮件”。 Outlook 是一个邮件客户端。您需要一个出站 SMTP 网关。在大多数情况下(如企业),Outlook 连接到 Microsoft Exchange 服务器,这是您将使用的 SMTP 网关。许多 ISP 不允许住宅客户推送 SMTP 邮件(因为僵尸网络和受感染的垃圾邮件计算机) 我不是从 Outlook 发送的。我是从组织提供的 SMTP 邮件服务器上做的。 @SPandya 无论哪种方式,只要确保您了解 SmtpClient 类在 SSL 方面的限制。【参考方案3】:

我收到了这个错误:

System.Net.Sockets.SocketException: An attempt was made to access a socket in a way forbidden by its access permissions

端口被另一个程序使用时

【讨论】:

【参考方案4】:

Windows 防火墙正在为我创建此错误。 SMTP 试图通过端口 587 向 GMAIL 发送邮件。将端口 587 添加到出站规则 [Outbound HTTP/SMTP/RDP] 解决了该问题。

【讨论】:

【参考方案5】:

如果其他答案不起作用,您可以使用 netstat 检查是否有其他东西正在使用该端口:

netstat -ano | findstr <your port number>

如果没有人在使用它,则可能会排除该端口,请尝试此命令以查看该范围是否被其他东西阻止:

netsh interface ipv4 show excludedportrange protocol=tcp

【讨论】:

检查排除的端口范围对我来说是诀窍。无法告诉我的应用程序的默认配置是使用排除范围,并且错误不会以任何方式表明这一点。【参考方案6】:

我也有同样的问题。它在本地机器上运行良好,但在服务器上出现问题。我更改了 SMTP 设置。对我来说效果很好。

如果您使用 GoDaddy Plesk 托管,请使用以下 SMTP 详细信息。

Host = relay-hosting.secureserver.net
Port = 25 

【讨论】:

这对于通过 Plesk 解决我的电子邮件问题非常有用。我的本地测试使用主机 smtpout.secureserver.com 工作,但当该站点在 Plesk 上运行时不断抛出错误。【参考方案7】:

如果您使用 GoDaddy,请执行此操作,如果您愿意,我正在使用 Lets Encrypt SSL。

这是代码 - 代码在 asp.net core 2.0 中,但应该可以在以上版本中使用。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using MailKit.Net.Smtp;
using MimeKit;

namespace UnityAssets.Website.Services

    public class EmailSender : IEmailSender
    
        public async Task SendEmailAsync(string toEmailAddress, string subject, string htmlMessage)
        
            var email = new MimeMessage();
            email.From.Add(new MailboxAddress("Application Name", "applicationId@gmail.com"));
            email.To.Add(new MailboxAddress(toEmailAddress, toEmailAddress));
            email.Subject = subject;

            var body = new BodyBuilder
            
                HtmlBody = htmlMessage
            ;

            email.Body = body.ToMessageBody();

            using (var client = new SmtpClient())
            
                //provider specific settings
                await client.ConnectAsync("smtp.gmail.com", 465, true).ConfigureAwait(false);
                await client.AuthenticateAsync("youremailid@gmail.com", "sketchunity").ConfigureAwait(false);

                await client.SendAsync(email).ConfigureAwait(false);
                await client.DisconnectAsync(true).ConfigureAwait(false);
            
        
    

【讨论】:

以上是关于使用 SMTP 时“尝试以访问权限禁止的方式访问套接字”的主要内容,如果未能解决你的问题,请参考以下文章

php WP Mail SMTP:使用SMTP邮件程序时 - 在PHP 5.6+上禁用SSL验证

SMTP使用Gmail发送电子邮件问题

为啥编码标头内容类型:text/html;在 Outlook 插件中使用 MailItem 时缺少 GMAIL 的 SMTP 服务器:SMTP.GMAIL.COM?

在 Asp.Net 中使用 Office365 SMTP 时出错

Django- [Errno 111] 使用 smtp 时连接被拒绝

使用 SMTP 时“尝试以访问权限禁止的方式访问套接字”