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.

Jake C
fonte

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.

Jake C
fonte
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á.

ADMITEM
fonte
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!

Sem logotipo
fonte
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 "[email protected]" (por exemplo: [email protected])
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.

Bill Mahoney
fonte
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
1
Localizei a
HFloyd
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 = "[email protected]";
string password = "password";
string mailFrom = "[email protected]";
string mailTo = "[email protected]";
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 = "[email protected]";
        string password = "password";
        string mailFrom = "[email protected]";
        string mailTo = "[email protected]";
        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);
        }
Martin Jaensson
fonte
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

1234varun
fonte
É 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.

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

Andy
fonte
2

Mude o seu número de porta de 465 para 587

Abdus Salam Azad
fonte
2

removendo

client.UseDefaultCredentials = false; 

parecia resolver isso para mim.

Goner Doug
fonte
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.

Nora
fonte
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;
            }
        }
    }
yasmuru
fonte
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.

Ajay Kumar
fonte
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

Hisham Shahid
fonte
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="[email protected]">
        <!-- Uncomment to specify SMTP settings -->
        <network host="domain.com" port="25" password="Jin@" userName="[email protected]"/>
      </smtp>
    </mailSettings>
Jin Thakur
fonte
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.

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

Evgeny Sobolev
fonte
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.

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

Shawn Wang
fonte