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 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.