SmtpException: Incapaz de ler os dados da conexão de transporte: net_io_connectionclosed


103

Estou usando a SmtpClientbiblioteca para enviar e-mails usando o seguinte:

SmtpClient client = new SmtpClient();
client.Host = "hostname";
client.Port = 465;
client.DeliveryMethod = SmtpDeliveryMethod.Network;
client.UseDefaultCredentials = false;
client.EnableSsl = true;
client.Credentials = new NetworkCredential("User", "Pass);
client.Send("from@hostname", "to@hostname", "Subject", "Body");

O código funciona bem em meu ambiente de teste, mas quando uso servidores SMTP de produção, o código falha com uma SmtpExceptionmensagem "Falha no envio de email". com um interno IOException"Não é possível ler dados da conexão de transporte: net_io_connectionclosed".

Confirmei que os firewalls não são um problema. A porta abre perfeitamente entre o cliente e o servidor. Não tenho certeza do que mais poderia gerar esse erro.

Respostas:


190

EDIT: Versão Super Redux

Tente a porta 587 em vez de 465. A porta 465 está tecnicamente obsoleta.


Depois de farejar um monte de pacotes, descobri. Primeiro, aqui está a resposta curta:

O .NET SmtpClient só oferece suporte à criptografia via STARTTLS. Se o EnableSslsinalizador for definido, o servidor deve responder ao EHLO com um STARTTLS, caso contrário, ele lançará uma exceção. Consulte a documentação do MSDN para obter mais detalhes.

Em segundo lugar, uma rápida lição de história do SMTP para aqueles que encontrarem esse problema no futuro:

No passado, quando os serviços também queriam oferecer criptografia, eles receberam um número de porta diferente e, nesse número de porta, iniciaram imediatamente uma conexão SSL. Com o passar do tempo, eles perceberam que era tolice desperdiçar dois números de porta em um serviço e criaram uma maneira de os serviços permitirem texto simples e criptografia na mesma porta usando STARTTLS. A comunicação seria iniciada usando texto simples e, em seguida, usando o comando STARTTLS para atualizar para uma conexão criptografada. STARTTLS se tornou o padrão para criptografia SMTP. Infelizmente, como sempre acontece quando um novo padrão é implementado, há uma confusão de compatibilidade com todos os clientes e servidores que existem.

No meu caso, meu usuário estava tentando conectar o software a um servidor que estava forçando uma conexão SSL imediata, que é o método legado que não é compatível com a Microsoft no .NET.


como posso saber se o servidor com o qual estou me conectando tem os mesmos problemas? Estou tentando usar SmtpClient com yahoo e / ou gmail e obtenho o erro descrito. Quando tento em um servidor Exchange 2013, meu código funciona bem.
— raider33

11
A maneira mais simples de testar é tentar usar a porta 587 e não 465. Embora alguns servidores SMTP suportem TLS em 465 (e às vezes até 25), apenas a porta 587 é necessária para suportar TLS. Além disso, o uso da porta 465 está obsoleto desde 1998 ( en.wikipedia.org/wiki/SMTPS ), embora na prática muitos servidores a tenham habilitado para clientes legados.
— Jake C

1
Sim, mudar para 587 resolveu o problema. Obrigado por me apontar na direção certa.
— raider33

2
587 funciona, embora smtp.att.yahaoo.com diga usar 465. Obrigado cara.
— Sam de

1
Para obter uma solução real, consulte stackoverflow.com/a/1014876/247702 sobre como usar o (obsoleto) System.Web.Mail que oferece suporte a SSL implícito.
— user247702

20

Mude a porta de 465 para 587 e funcionará.


3
Não tenho certeza do que aconteceu, mas isso funciona comigo usando gmail smtp. você pode explicar por que isso funciona?
— Crismograma

20

Para qualquer pessoa que se depara com esta postagem procurando uma solução e você configurou o sendgrid SMTP via Azure.

O nome de usuário não é o nome de usuário que você configurou quando criou o objeto sendgrid no azure. Para encontrar seu nome de usuário;

  • Clique em seu objeto sendgrid no azul e clique em gerenciar. Você será redirecionado para o site SendGrid.
  • Confirme seu e-mail e anote o nome de usuário exibido lá .. é um nome de usuário gerado automaticamente.
  • Adicione o nome de usuário do SendGrid às configurações de SMTP no arquivo web.config.

Espero que isto ajude!


2
Pode parecer bobagem, mas outra coisa que você pode querer verificar é se a senha está correta para a configuração do SendGrid SMTP. Nossa configuração estava funcionando originalmente e um dia começamos a receber a mensagem de exceção do OP. As pesquisas na WWW apontavam principalmente para a observação de outras configurações do servidor SMTP, quando eventualmente descobriram que a senha estava incorreta. Alguém na equipe alterou a senha no arquivo de configuração para uma variação em que a primeira letra não estava em maiúscula.
— methon.dagger

1
No meu caso, o nome de usuário estava incorreto e com erro de digitação. Mas uma senha errada também pode dar a mensagem "Incapaz de ler dados da conexão de transporte: net_io_connectionclosed." erro. Portanto, verifique o nome de usuário e a senha. E para usuários do Azure, o nome de usuário tem o formato "azure_guid-withoutdashes@azure.com" (por exemplo: azure_e9e062db4bfd491296bec77bcff49ed9@azure.com)
— Raj Rao

10

Você também pode ter que alterar a configuração "aplicativos menos seguros" na sua conta do Gmail. EnableSsl, use a porta 587 e habilite "aplicativos menos seguros". Se você pesquisar no Google a parte de aplicativos menos seguros, há páginas de ajuda do Google que o vincularão diretamente à página de sua conta. Esse era o meu problema, mas agora está tudo funcionando graças a todas as respostas acima.


Obrigado Bill. Isso ainda funciona com minha conta padrão do gmail. Se você não usar a configuração "aplicativos menos seguros", terá que usar a autenticação OAuth2 de 2 partes. Isso não é prático quando você deseja apenas enviar um e-mail de confirmação de um site.
— Dan Randolph

1
Onde estão os "aplicativos menos seguros" se estabelecendo. Estou em minha conta do gmail procurando por ele.
— Sam


9

Tentei todas as respostas acima, mas ainda recebo esse erro com a conta do Office 365. O código parece funcionar bem com a conta do Google e smtp.gmail.com ao permitir aplicativos menos seguros.

Alguma outra sugestão que eu pudesse tentar?

Aqui está o código que estou usando

int port = 587;
string host = "smtp.office365.com";
string username = "smtp.out@mail.com";
string password = "password";
string mailFrom = "noreply@mail.com";
string mailTo = "to@mail.com";
string mailTitle = "Testtitle";
string mailMessage = "Testmessage";

using (SmtpClient client = new SmtpClient())
{
    MailAddress from = new MailAddress(mailFrom);
    MailMessage message = new MailMessage
    {
        From = from
    };
    message.To.Add(mailTo);
    message.Subject = mailTitle;
    message.Body = mailMessage;
    message.IsBodyHtml = true;
    client.DeliveryMethod = SmtpDeliveryMethod.Network;
    client.UseDefaultCredentials = false;
    client.Host = host;
    client.Port = port;
    client.EnableSsl = true;
    client.Credentials = new NetworkCredential
    {
        UserName = username,
        Password = password
    }; 
    client.Send(message);
}

ATUALIZAÇÃO E COMO RESOLVEI:

Resolvido o problema alterando o cliente Smtp para Mailkit. O cliente Smtp System.Net.Mail agora não é recomendado para uso pela Microsoft devido a problemas de segurança e você deve usar o MailKit. O uso do Mailkit gerou mensagens de erro mais claras que pude entender, encontrando a causa raiz do problema (problema de licença). Você pode obter o Mailkit baixando-o como um pacote Nuget .

Leia a documentação sobre o cliente Smtp para obter mais informações: https://docs.microsoft.com/es-es/dotnet/api/system.net.mail.smtpclient?redirectedfrom=MSDN&view=netframework-4.7.2

Aqui está como eu implementei SmtpClient com MailKit

        int port = 587;
        string host = "smtp.office365.com";
        string username = "smtp.out@mail.com";
        string password = "password";
        string mailFrom = "noreply@mail.com";
        string mailTo = "mailto@mail.com";
        string mailTitle = "Testtitle";
        string mailMessage = "Testmessage";

        var message = new MimeMessage();
        message.From.Add(new MailboxAddress(mailFrom));
        message.To.Add(new MailboxAddress(mailTo));
        message.Subject = mailTitle;
        message.Body = new TextPart("plain") { Text = mailMessage };

        using (var client = new SmtpClient())
        {
            client.Connect(host , port, SecureSocketOptions.StartTls);
            client.Authenticate(username, password);

            client.Send(message);
            client.Disconnect(true);
        }

3

A sua biblioteca SMTP oferece suporte para conexão criptografada? O servidor de e-mail pode estar esperando uma conexão TLS segura e, portanto, fechando a conexão na ausência de um handshake TLS


É apenas a SmtpClientbiblioteca .NET padrão , ela oferece suporte a criptografia, o servidor requer criptografia e eu a configurei client.EnableSssl = true;. Embora eu ache que vou prosseguir um pouco mais com o Wireshark.
— Jake C

3

Se você estiver usando um servidor SMTP na mesma caixa e seu SMTP estiver vinculado a um endereço IP em vez de "Qualquer atribuído", ele pode falhar porque está tentando usar um endereço IP (como 127.0.0.1) que o SMTP não está funcionando atualmente em.


2

Para elevar o que jocull mencionou em um comentário, eu estava fazendo tudo mencionado neste tópico e eliminando ... porque o meu estava em um loop para ser atropelado continuamente; após a primeira vez no loop, às vezes ele falhava. Sempre trabalhei pela primeira vez no loop.

Para ficar claro: o loop inclui a criação de SmtpClient e, em seguida, fazer .Send com os dados corretos. O SmtpClient foi criado dentro de um bloco try / catch, para detectar erros e ter certeza de que o objeto foi destruído antes do final do loop.

No meu caso, a solução foi garantir que SmtpClient fosse descartado após cada vez no loop (seja por meio da instrução using () ou fazendo um descarte manual). Mesmo se o objeto SmtpClient estiver sendo destruído implicitamente no loop, o .NET parece estar deixando coisas por aí para entrar em conflito com a próxima tentativa.



2

removendo

client.UseDefaultCredentials = false; 

parecia resolver isso para mim.


1

No meu caso, o cliente esqueceu de adicionar um novo endereço IP em suas configurações de SMTP. Abra o IIS 6.0 no servidor que configura o smtp, clique com o botão direito do mouse no servidor virtual Smtp, escolha Propriedades, guia Acesso, clique em Conexões, adicione o endereço IP do novo servidor. Em seguida, clique em Relay e adicione também o endereço IP do novo servidor. Isso resolveu meu problema.


0

Tente isto: aqui está o código que estou usando para enviar e-mails para vários usuários.

 public string gmail_send()
    {
        using (MailMessage mailMessage =
        new MailMessage(new MailAddress(toemail),
    new MailAddress(toemail)))
        {
            mailMessage.Body = body;
            mailMessage.Subject = subject;
            try
            {
                SmtpClient SmtpServer = new SmtpClient();
                SmtpServer.Credentials =
                    new System.Net.NetworkCredential(email, password);
                SmtpServer.Port = 587;
                SmtpServer.Host = "smtp.gmail.com";
                SmtpServer.EnableSsl = true;
                mail = new MailMessage();
                String[] addr = toemail.Split(','); // toemail is a string which contains many email address separated by comma
                mail.From = new MailAddress(email);
                Byte i;
                for (i = 0; i < addr.Length; i++)
                    mail.To.Add(addr[i]);
                mail.Subject = subject;
                mail.Body = body;
                mail.IsBodyHtml = true;
                mail.DeliveryNotificationOptions =
                    DeliveryNotificationOptions.OnFailure;
                //   mail.ReplyTo = new MailAddress(toemail);
                mail.ReplyToList.Add(toemail);
                SmtpServer.Send(mail);
                return "Mail Sent";
            }
            catch (Exception ex)
            {
                string exp = ex.ToString();
                return "Mail Not Sent ... and ther error is " + exp;
            }
        }
    }

1
SmtpClienttambém é Descartável, por isso deve ser embrulhado em um usingbloco
— jocull de

0

No caso de todas as soluções acima não funcionarem para você, tente atualizar o arquivo a seguir para o seu servidor (por publicação, quero dizer, e uma compilação anterior seria útil).

bin-> projectname.dll 

Após a atualização, você verá este erro. como eu resolvi com esta solução.


1
Surpreendentemente, isso funcionou para mim! Permitir aplicativos inseguros estava ativado e a porta já estava definida como 587.
— TechyGypo

Obrigado, acabei de perceber que não era o único com esse problema. feliz por ajudar.
— Ajay Kumar de

0

Para o Outlook, use a configuração a seguir que não está me dando erro

Nome do servidor SMTP smtp-mail.outlook.com

Porta SMTP 587


0

Este erro é muito genérico. Pode ser devido a vários motivos, como O servidor de e-mail está incorreto. Algumas empresas de hospedagem usam o formato mail.domainname. Se você apenas usar o nome de domínio, não funcionará. verifique as credenciais nome do host nome do usuário senha, se necessário Verifique com a empresa de hospedagem.

<smtp from="info@india.uu.com">
        <!-- Uncomment to specify SMTP settings -->
        <network host="domain.com" port="25" password="Jin@" userName="info@india.xx.com"/>
      </smtp>
    </mailSettings>

0

No meu caso, o IP do servidor web foi bloqueado no servidor de e-mail, ele precisa ser desbloqueado pela empresa de hospedagem e colocá-lo na lista de permissões. Além disso, use a porta 587.


0

Se o seu servidor de e-mail for Gmail (smtp.google.com), você receberá este erro quando atingir o limite de mensagens. O Gmail permite o envio por SMTP de até 2.000 mensagens por 24 horas.


0

Corri para isso ao usar smtp.office365.com, usando a porta 587 com SSL. Consegui fazer login na conta usando portal.office.com e confirmei que a conta tinha uma licença. Mas quando disparei o código para enviar e-mails, continuei recebendo o erro net_io_connectionclosed.

Levei algum tempo para descobrir, mas o administrador do Exchange encontrou o culpado. Estamos usando o O365, mas o servidor Exchange estava em um ambiente híbrido. Embora a conta que estávamos tentando usar fosse sincronizada com o Azure AD e tivesse uma licença válida do O365, por algum motivo a caixa de correio ainda residia no servidor Exchange híbrido - não no Exchange online. Depois que o administrador do Exchange usou o comando "Move-Mailbox" para mover a caixa de correio do servidor híbrido do Exchange para o O365, poderíamos usar o código para enviar e-mails usando o 365.


-1

Prepare: 1. HostA é o servidor virtual SMTP com porta padrão 25 2. HostB é uma estação de trabalho na qual eu envio e-mail com SmtpClient e simulo uma rede instável que uso desajeitado

Caso 1 fornecido se HostB for 2008R2 Quando eu enviar e-mail. Então esse problema ocorre.

Caso 2 fornecido se HostB for 2012 ou uma versão superior quando eu enviar e-mail. Em seguida, o e-mail foi enviado.

Conclusão: essa causa raiz está relacionada ao Windows Server 2008R2.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.