SmtpException: no se pueden leer datos de la conexión de transporte: net_io_connectionclosed

103

Estoy usando la SmtpClientbiblioteca para enviar correos electrónicos usando lo siguiente:

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");

El código funciona bien en mi entorno de prueba, pero cuando utilizo servidores SMTP de producción, el código falla con un SmtpException"Error al enviar correo". con un interior IOException"No se pueden leer datos de la conexión de transporte: net_io_connectionclosed".

Confirmé que los firewalls no son un problema. El puerto se abre bien entre el cliente y el servidor. No estoy seguro de qué más podría arrojar este error.

Jake C
fuente

Respuestas:

190

EDITAR: Versión Super Redux

Pruebe el puerto 587 en lugar del 465. El puerto 465 está técnicamente en desuso.


Después de un montón de oler paquetes, lo descubrí. Primero, aquí está la respuesta corta:

.NET SmtpClient solo admite el cifrado a través de STARTTLS. Si EnableSslse establece la bandera, el servidor debe responder a EHLO con STARTTLS, de lo contrario lanzará una excepción. Consulte la documentación de MSDN para obtener más detalles.

En segundo lugar, una rápida lección de historia de SMTP para aquellos que se encuentren con este problema en el futuro:

En el pasado, cuando los servicios querían ofrecer también cifrado, se les asignaba un número de puerto diferente y en ese número de puerto iniciaban inmediatamente una conexión SSL. A medida que pasaba el tiempo, se dieron cuenta de que era una tontería desperdiciar dos números de puerto para un servicio e idearon una forma para que los servicios permitieran texto sin formato y cifrado en el mismo puerto utilizando STARTTLS. La comunicación comenzaría a usar texto sin formato, luego usaría el comando STARTTLS para actualizar a una conexión encriptada. STARTTLS se convirtió en el estándar para el cifrado SMTP. Desafortunadamente, como siempre sucede cuando se implementa un nuevo estándar, existe una mezcolanza de compatibilidad con todos los clientes y servidores que existen.

En mi caso, mi usuario intentaba conectar el software a un servidor que estaba forzando una conexión SSL inmediata, que es el método heredado que no es compatible con Microsoft en .NET.

Jake C
fuente
¿Cómo puedo saber si el servidor con el que me estoy conectando tiene los mismos problemas? Estoy tratando de usar SmtpClient con yahoo y / o gmail y obtengo el error descrito. Cuando intento contra un servidor de intercambio de 2013, mi código funciona bien.
raider33
11
La forma más sencilla de realizar la prueba es intentar usar el puerto 587 y no el 465. Si bien algunos servidores SMTP admiten TLS en 465 (ya veces incluso 25), solo se requiere el puerto 587 para admitir TLS. Además de eso, el uso del puerto 465 ha quedado obsoleto desde 1998 ( en.wikipedia.org/wiki/SMTPS ), aunque en la práctica muchos servidores lo tienen habilitado para clientes heredados.
Jake C
1
Sí, cambiar a 587 funcionó. Gracias por señalarme en la dirección correcta.
raider33
2
587 funciona aunque smtp.att.yahaoo.com dice que use 465. Gracias tío.
Sam
1
Para obtener una solución real, consulte stackoverflow.com/a/1014876/247702 sobre el uso de System.Web.Mail (obsoleto), que admite SSL implícito.
user247702
20

Cambie el puerto de 465 a 587 y funcionará.

ADMITIR
fuente
3
No estoy seguro de lo que sucedió, pero esto me funciona usando gmail smtp. ¿puedes explicar por qué esto funciona?
Crismograma
20

Para cualquiera que se encuentre con esta publicación en busca de una solución y haya configurado SMTP sendgrid a través de Azure.

El nombre de usuario no es el nombre de usuario que configuró cuando creó el objeto sendgrid en azul. Para encontrar su nombre de usuario;

  • Haga clic en su objeto sendgrid en azul y haga clic en administrar. Será redirigido al sitio de SendGrid.
  • Confirme su correo electrónico y luego copie el nombre de usuario que se muestra allí ... es un nombre de usuario generado automáticamente.
  • Agregue el nombre de usuario de SendGrid en su configuración SMTP en el archivo web.config.

¡Espero que esto ayude!

Sin logo
fuente
2
Esto puede parecer una tontería, pero otra cosa que quizás desee comprobar es si la contraseña es correcta para la configuración de SMTP SendGrid. Nuestra configuración estaba funcionando originalmente y un día comenzamos a recibir el mensaje de excepción del OP. Las búsquedas en la WWW apuntaban principalmente a buscar otras configuraciones de servidor SMTP cuando finalmente resultó que la contraseña era incorrecta. Alguien del equipo había cambiado la contraseña en el archivo de configuración a una variación en la que la primera letra no estaba en mayúscula.
methon.dagger
1
En mi caso, el nombre de usuario era incorrecto y tenía un error tipográfico. Pero una contraseña incorrecta también puede dar el mensaje "No se pueden leer los datos de la conexión de transporte: net_io_connectionclosed". error. Así que verifique tanto el nombre de usuario como la contraseña. Y para los usuarios de Azure, el nombre de usuario tiene el formato "[email protected]" (por ejemplo: [email protected])
Raj Rao
10

Es posible que también deba cambiar la configuración de "aplicaciones menos seguras" en su cuenta de Gmail. EnableSsl, use el puerto 587 y habilite "aplicaciones menos seguras". Si busca en Google la parte de aplicaciones menos seguras, hay páginas de ayuda de Google que lo vincularán directamente a la página de su cuenta. Ese era mi problema, pero todo está funcionando ahora gracias a todas las respuestas anteriores.

Bill Mahoney
fuente
Gracias Bill. Esto todavía funciona con mi cuenta de Gmail estándar. Si no usa la configuración de "aplicaciones menos seguras", debe usar la autenticación de dos partes OAuth2. Esto no es práctico cuando solo desea enviar un correo electrónico de confirmación desde un sitio web.
Dan Randolph
1
¿Dónde está la configuración de "aplicaciones menos seguras"? Estoy en mi cuenta de gmail buscándolo.
Sam
1
Encontré la configuración de "Aplicaciones menos seguras"; no está en la configuración de Gmail, sino en la configuración de la cuenta de Google: Mi cuenta> Inicio de
HFloyd
9

Probé todas las respuestas anteriores, pero sigo recibiendo este error con la cuenta de Office 365. El código parece funcionar bien con la cuenta de Google y smtp.gmail.com cuando se permiten aplicaciones menos seguras.

¿Alguna otra sugerencia que pueda probar?

Aquí está el código que estoy 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);
}

ACTUALIZACIÓN Y CÓMO LO RESUELVE:

Problema resuelto cambiando Smtp Client a Mailkit. Microsoft no recomienda el uso del Cliente Smtp System.Net.Mail debido a problemas de seguridad y, en su lugar, debería utilizar MailKit. El uso de Mailkit me dio mensajes de error más claros que podía entender para encontrar la causa raíz del problema (problema de licencia). Puede obtener Mailkit descargándolo como un paquete Nuget .

Lea la documentación sobre Smtp Client para obtener más información: https://docs.microsoft.com/es-es/dotnet/api/system.net.mail.smtpclient?redirectedfrom=MSDN&view=netframework-4.7.2

Así es como implementé SmtpClient con 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
fuente
3

¿Su biblioteca SMTP admite una conexión cifrada? El servidor de correo puede estar esperando una conexión TLS segura y, por lo tanto, cerrar la conexión en ausencia de un protocolo de enlace TLS

1234varun
fuente
Es solo la SmtpClientbiblioteca .NET predeterminada , admite el cifrado, el servidor requiere cifrado y lo he configurado client.EnableSssl = true;. Aunque creo que voy a persistir un poco más en esto con Wireshark.
Jake C
3

Si está utilizando un servidor SMTP en la misma caja y su SMTP está vinculado a una dirección IP en lugar de "Cualquiera asignada", puede fallar porque está intentando usar una dirección IP (como 127.0.0.1) que SMTP no está funcionando actualmente. en.

Josías
fuente
2

Para elevar lo que jocull mencionó en un comentario, estaba haciendo todo lo que se menciona en este hilo y tachando ... porque el mío estaba en un bucle para que se repitiera una y otra vez; después de la primera vez que pasaba por el bucle, a veces fallaba. Siempre trabajó la primera vez a través del bucle.

Para ser claros: el bucle incluye la creación de SmtpClient y luego hacer .Send con los datos correctos. El SmtpClient se creó dentro de un bloque try / catch, para detectar errores y asegurarse de que el objeto se destruyó antes del final del ciclo.

En mi caso, la solución fue asegurarse de que SmtpClient se eliminara después de cada vez en el ciclo (ya sea mediante la instrucción using () o mediante una eliminación manual). Incluso si el objeto SmtpClient se destruye implícitamente en el ciclo, .NET parece estar dejando cosas por ahí que entran en conflicto con el próximo intento.

Andy
fuente
2

Cambie su número de puerto de 465 a 587

Abdus Salam Azad
fuente
2

quitar

client.UseDefaultCredentials = false; 

pareció resolverlo por mí.

Goner Doug
fuente
1

En caso de que todas las soluciones anteriores no funcionen para usted, intente actualizar el siguiente archivo en su servidor (me refiero a publicar, y una compilación anterior sería útil).

bin-> projectname.dll 

Después de la actualización, verá este error. como he resuelto con esta solución.

Ajay Kumar
fuente
1
¡Sorprendentemente esto funcionó para mí! Permitir aplicaciones inseguras estaba activado y el puerto ya estaba configurado en 587.
TechyGypo
Gracias, me acabo de dar cuenta de que no soy el único con este problema. feliz de ayudar.
Ajay Kumar
1

En mi caso, el cliente olvidó agregar una nueva dirección IP en su configuración SMTP. Abra IIS 6.0 en el servidor que configura el smtp, haga clic con el botón derecho en el servidor virtual Smtp, elija Propiedades, pestaña Acceso, haga clic en Conexiones, agregue la dirección IP del nuevo servidor. Luego haga clic en Relay, también agregue la dirección IP del nuevo servidor. Esto resolvió mi problema.

Nora
fuente
0

Pruebe esto: aquí está el código que estoy usando para enviar correos electrónicos a varios usuarios.

 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
fuente
1
SmtpClienttambién es desechable, por lo que debe envolverse en un usingbloque
jocull
0

Para Outlook use la siguiente configuración que no me está dando error

Nombre del servidor SMTP smtp-mail.outlook.com

Puerto SMTP 587

Hisham shahid
fuente
0

Este error es muy genérico. Puede deberse a muchas razones, como El servidor de correo es incorrecto. Algunas empresas de alojamiento utilizan el formato mail.domainname. Si solo usa el nombre de dominio, no funcionará. compruebe las credenciales nombre de host nombre de usuario contraseña si es necesario Consulte con la empresa de alojamiento.

<smtp from="[email protected]">
        <!-- Uncomment to specify SMTP settings -->
        <network host="domain.com" port="25" password="Jin@" userName="[email protected]"/>
      </smtp>
    </mailSettings>
Jin Thakur
fuente
0

En mi caso, la IP del servidor web se bloqueó en el servidor de correo, su empresa de alojamiento debe desbloquearla y ponerla en la lista blanca. Además, use el puerto 587.

Zsolt
fuente
0

Si su servidor de correo es Gmail (smtp.google.com), recibirá este error cuando alcance el límite de mensajes. Gmail permite enviar a través de SMTP hasta solo 2000 mensajes por 24 horas.

Evgeny Sobolev
fuente
0

Me encontré con esto cuando usaba smtp.office365.com, usando el puerto 587 con SSL. Pude iniciar sesión en la cuenta usando portal.office.com y pude confirmar que la cuenta tenía una licencia. Pero cuando disparé el código para enviar correos electrónicos, seguí recibiendo el error net_io_connectionclosed.

Me tomó algo de tiempo resolverlo, pero el administrador de Exchange encontró al culpable. Estamos usando O365 pero el servidor Exchange estaba en un entorno híbrido. Aunque la cuenta que intentábamos usar estaba sincronizada con Azure AD y tenía una licencia válida de O365, por alguna razón, el buzón aún residía en el servidor híbrido de Exchange, no en Exchange online. Después de que el administrador de intercambio usó el comando "Move-Mailbox" para mover el buzón del servidor de intercambio híbrido a O365, pudimos usar el código para enviar correos electrónicos usando o365.

iki58762
fuente
-1

Prepare: 1. HostA es un servidor virtual SMTP con el puerto predeterminado 25 2. HostB es una estación de trabajo en la que envío correo con SmtpClient y simulo una red inestable que uso torpe

Caso 1 dado si HostB es 2008R2 cuando envío un correo electrónico. Entonces ocurre este problema.

Caso 2 dado si HostB es 2012 o una versión superior cuando envío un correo electrónico. Luego se envió el correo.

Conclusión: esta causa raíz está relacionada con Windows Server 2008R2.

Shawn Wang
fuente