SmtpException: impossible de lire les données de la connexion de transport: net_io_connectionclosed


103

J'utilise la SmtpClientbibliothèque pour envoyer des e-mails en utilisant les éléments suivants:

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

Le code fonctionne correctement dans mon environnement de test, mais lorsque j'utilise des serveurs SMTP de production, le code échoue avec un SmtpException«Échec de l'envoi du courrier». avec un IOException"Impossible de lire les données de la connexion de transport: net_io_connectionclosed".

J'ai confirmé que les pare-feu ne sont pas un problème. Le port s'ouvre très bien entre le client et le serveur. Je ne sais pas quoi d'autre pourrait provoquer cette erreur.

Réponses:


190

EDIT: Version Super Redux

Essayez le port 587 au lieu de 465. Le port 465 est techniquement obsolète.


Après un tas de reniflements de paquets, je l'ai compris. Tout d'abord, voici la réponse courte:

Le .NET prend SmtpClient uniquement en charge le chiffrement via STARTTLS. Si l' EnableSslindicateur est défini, le serveur doit répondre à EHLO avec un STARTTLS, sinon il lèvera une exception. Consultez la documentation MSDN pour plus de détails.

Deuxièmement, une petite leçon d'histoire SMTP pour ceux qui tomberont sur ce problème à l'avenir:

À l'époque, lorsque les services voulaient également offrir le cryptage, ils se voyaient attribuer un numéro de port différent et, sur ce numéro de port, ils ont immédiatement lancé une connexion SSL. Au fil du temps, ils ont réalisé qu'il était ridicule de gaspiller deux numéros de port pour un service et ils ont conçu un moyen pour les services d'autoriser le texte en clair et le cryptage sur le même port en utilisant STARTTLS. La communication commencerait à utiliser du texte brut, puis utiliserait la commande STARTTLS pour passer à une connexion chiffrée. STARTTLS est devenu la norme pour le cryptage SMTP. Malheureusement, comme cela arrive toujours lorsqu'une nouvelle norme est mise en œuvre, il existe un méli-mélo de compatibilité avec tous les clients et serveurs.

Dans mon cas, mon utilisateur essayait de connecter le logiciel à un serveur qui forçait une connexion SSL immédiate, qui est la méthode héritée qui n'est pas prise en charge par Microsoft dans .NET.


comment puis-je savoir si le serveur avec lequel je me connecte présente les mêmes problèmes? J'essaye d'utiliser SmtpClient avec yahoo et / ou gmail et obtenir l'erreur décrite. Quand j'essaye contre un serveur d'échange 2013, mon code fonctionne bien.
raider33

11
Le moyen le plus simple de tester est d'essayer d'utiliser le port 587 et non 465. Alors que certains serveurs SMTP prennent en charge TLS sur 465 (et parfois même 25), seul le port 587 est requis pour prendre en charge TLS. En plus de cela, l'utilisation du port 465 est obsolète depuis 1998 ( en.wikipedia.org/wiki/SMTPS ), bien qu'en pratique de nombreux serveurs l'aient activé pour les clients hérités.
Jake C

1
Oui, passer à 587 a fait l'affaire. Merci de m'avoir pointé dans la bonne direction.
raider33

2
587 fonctionne bien que smtp.att.yahaoo.com indique utiliser 465. Merci mec.
Sam

1
Pour une solution réelle, voir stackoverflow.com/a/1014876/247702 sur l'utilisation de System.Web.Mail (obsolète) qui prend en charge SSL implicite.
user247702

20

Changez le port de 465 à 587 et cela fonctionnera.


3
Je ne suis pas sûr de ce qui s'est passé, mais cela me fonctionne avec gmail smtp. pouvez-vous expliquer pourquoi cela fonctionne?
Crismogram

20

Pour tous ceux qui tombent sur ce post à la recherche d'une solution et que vous avez configuré sendgrid SMTP via Azure.

Le nom d'utilisateur n'est pas le nom d'utilisateur que vous avez configuré lorsque vous avez créé l'objet sendgrid dans azure. Pour trouver votre nom d'utilisateur;

  • Cliquez sur votre objet sendgrid dans azure et cliquez sur gérer. Vous serez redirigé vers le site SendGrid.
  • Confirmez votre e-mail puis copiez le nom d'utilisateur qui y est affiché .. c'est un nom d'utilisateur généré automatiquement.
  • Ajoutez le nom d'utilisateur de SendGrid dans vos paramètres SMTP dans le fichier web.config.

J'espère que cela t'aides!


2
Cela peut sembler idiot, mais vous voudrez peut-être vérifier si le mot de passe est correct pour la configuration SMTP SendGrid. Notre configuration fonctionnait à l'origine et un jour, nous avons commencé à recevoir le message d'exception de l'OP. Les recherches sur le WWW indiquaient principalement de regarder d'autres configurations de serveur SMTP quand finalement il s'est avéré que le mot de passe était incorrect. Un membre de l'équipe avait changé le mot de passe dans le fichier de configuration en une variante où la première lettre n'était pas en majuscule.
methon.dagger

1
Dans mon cas, le nom d'utilisateur était incorrect et contenait une faute de frappe. Mais un mot de passe incorrect peut également donner le message «Impossible de lire les données de la connexion de transport: net_io_connectionclosed». Erreur. Vérifiez donc à la fois le nom d'utilisateur et le mot de passe. Et pour les utilisateurs Azure, le nom d'utilisateur est de la forme "azure_guid-withoutdashes@azure.com" (par exemple: azure_e9e062db4bfd491296bec77bcff49ed9@azure.com)
Raj Rao

10

Vous devrez peut-être également modifier le paramètre "Applications moins sécurisées" de votre compte Gmail. EnableSsl, utilisez le port 587 et activez les «applications moins sécurisées». Si vous recherchez sur Google la partie des applications les moins sécurisées, il existe des pages d'aide Google qui vous relieront directement à la page de votre compte. C'était mon problème mais tout fonctionne maintenant grâce à toutes les réponses ci-dessus.


Merci Bill. Cela fonctionne toujours avec mon compte Gmail standard. Si vous n'utilisez pas le paramètre "Applications moins sécurisées", vous devez utiliser l'authentification en deux parties OAuth2. Ce n'est pas pratique lorsque vous souhaitez simplement envoyer un e-mail de confirmation à partir d'un site Web.
Dan Randolph

1
Où se situent les «applications les moins sécurisées». Je suis dans mon compte Gmail à la recherche.
Sam le

1
J'ai localisé le paramètre "Applications moins sécurisées" - il ne se trouve pas dans les paramètres Gmail, mais dans les paramètres de compte Google: Mon compte> Connexion et sécurité myaccount.google.com
...

9

J'ai essayé toutes les réponses ci-dessus mais j'obtiens toujours cette erreur avec le compte Office 365. Le code semble fonctionner correctement avec le compte Google et smtp.gmail.com lorsque vous autorisez des applications moins sécurisées.

D'autres suggestions que je pourrais essayer?

Voici le code que j'utilise

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

MISE À JOUR ET COMMENT JE LE RÉSOLU:

Problème résolu en changeant Smtp Client en Mailkit. L'utilisation du client Smtp System.Net.Mail n'est désormais pas recommandée par Microsoft en raison de problèmes de sécurité et vous devriez plutôt utiliser MailKit. L'utilisation de Mailkit m'a donné des messages d'erreur plus clairs que je pouvais comprendre pour trouver la cause première du problème (problème de licence). Vous pouvez obtenir Mailkit en le téléchargeant en tant que package Nuget .

Consultez la documentation sur Smtp Client pour plus d'informations: https://docs.microsoft.com/es-es/dotnet/api/system.net.mail.smtpclient?redirectedfrom=MSDN&view=netframework-4.7.2

Voici comment j'ai implémenté SmtpClient avec 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

Votre bibliothèque SMTP prend-elle en charge la connexion cryptée? Le serveur de messagerie peut s'attendre à une connexion TLS sécurisée et, par conséquent, fermer la connexion en l'absence d'une négociation TLS


C'est juste la SmtpClientbibliothèque .NET par défaut , elle prend en charge encrytpion, le serveur nécessite un cryptage, et j'ai défini client.EnableSssl = true;. Bien que je pense que je vais poursuivre cela un peu plus loin avec Wireshark.
Jake C du

3

Si vous utilisez un serveur SMTP sur le même boîtier et que votre SMTP est lié à une adresse IP au lieu de «Any Assigned», il peut échouer car il tente d'utiliser une adresse IP (comme 127.0.0.1) que SMTP ne fonctionne pas actuellement sur.


2

Pour élever ce que jocull a mentionné dans un commentaire, je faisais tout ce qui est mentionné dans ce fil et je rayais ... parce que le mien était dans une boucle à répéter encore et encore; après la première fois dans la boucle, il échouait parfois. Toujours travaillé la première fois dans la boucle.

Pour être clair: la boucle comprend la création de SmtpClient, puis faire .Send avec les bonnes données. Le SmtpClient a été créé à l'intérieur d'un bloc try / catch, pour attraper les erreurs et pour être sûr que l'objet a été détruit avant le bas de la boucle.

Dans mon cas, la solution était de s'assurer que SmtpClient était supprimé après chaque fois dans la boucle (soit via l'instruction using (), soit en effectuant une suppression manuelle). Même si l'objet SmtpClient est implicitement détruit dans la boucle, .NET semble laisser des éléments traîner en conflit avec la prochaine tentative.



2

enlever

client.UseDefaultCredentials = false; 

semblait le résoudre pour moi.


1

Dans mon cas, le client a oublié d'ajouter une nouvelle adresse IP dans ses paramètres SMTP. Ouvrez IIS 6.0 dans le serveur qui configure le smtp, cliquez avec le bouton droit sur le serveur virtuel Smtp, choisissez Propriétés, onglet Accès, cliquez sur Connexions, ajoutez l'adresse IP du nouveau serveur. Cliquez ensuite sur Relais, ajoutez également l'adresse IP du nouveau serveur. Cela a résolu mon problème.


0

Essayez ceci: voici le code que j'utilise pour envoyer des e-mails à plusieurs utilisateurs.

 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
SmtpClientest également jetable, il doit donc être emballé dans un usingbloc
jocull

0

Si toutes les solutions ci-dessus ne fonctionnent pas pour vous, essayez de mettre à jour le fichier suivant sur votre serveur (par publication, je veux dire, et une version antérieure serait utile).

bin-> projectname.dll 

Après la mise à jour, vous verrez cette erreur. comme je l'ai résolu avec cette solution.


1
Étonnamment, cela a fonctionné pour moi! Autoriser les applications non sécurisées était activé et le port était déjà défini sur 587.
TechyGypo le

Merci, je viens de réaliser que je n'étais pas le seul à avoir ce problème. heureux d'aider.
Ajay Kumar

0

Pour Outlook, utilisez le paramètre suivant qui ne me donne pas d'erreur

Nom du serveur SMTP smtp-mail.outlook.com

Port SMTP 587


0

Cette erreur est très générique. Elle peut être due à plusieurs raisons telles que le serveur de messagerie est incorrect. Certains hébergeurs utilisent le format mail.domainname. Si vous utilisez simplement un nom de domaine, cela ne fonctionnera pas. vérifiez les informations d'identification nom d'hôte nom d'utilisateur mot de passe si nécessaire Vérifiez auprès de la société d'hébergement.

<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

Dans mon cas, l'adresse IP du serveur Web a été bloquée sur le serveur de messagerie, elle doit être débloquée par votre société d'hébergement et la mettre sur la liste blanche. Utilisez également le port 587.


0

Si votre serveur de messagerie est Gmail (smtp.google.com), vous obtiendrez cette erreur lorsque vous atteindrez la limite de messages. Gmail permet d'envoyer sur SMTP jusqu'à 2000 messages par 24 heures.


0

J'ai rencontré cela lors de l'utilisation de smtp.office365.com, en utilisant le port 587 avec SSL. J'ai pu me connecter au compte en utilisant portal.office.com et j'ai pu confirmer que le compte possédait une licence. Mais lorsque j'ai déclenché le code pour envoyer des e-mails, j'ai continué à recevoir l'erreur net_io_connectionclosed.

Il m'a fallu un certain temps pour le comprendre, mais l'administrateur Exchange a trouvé le coupable. Nous utilisons O365 mais le serveur Exchange était dans un environnement hybride. Bien que le compte que nous essayions d'utiliser ait été synchronisé avec Azure AD et possédait une licence O365 valide, pour une raison quelconque, la boîte aux lettres résidait toujours sur le serveur Exchange hybride, et non sur Exchange en ligne. Après que l'administrateur de l'échange a utilisé la commande «Déplacer la boîte aux lettres» pour déplacer la boîte aux lettres du serveur d'échange hybride vers O365, nous pourrions utiliser le code pour envoyer des e-mails en utilisant o365.


-1

Préparez: 1. HostA est un serveur virtuel SMTP avec le port par défaut 25 2. HostB est un poste de travail sur lequel j'envoie du courrier avec SmtpClient et simule un réseau instable J'utilise maladroit

Cas 1 donné si HostB est 2008R2 Lorsque j'envoie un e-mail. Ensuite, ce problème se produit.

Cas 2 donné si HostB est 2012 ou version supérieure Lorsque j'envoie un e-mail. Ensuite, le courrier a été envoyé.

Conclusion: cette cause première est liée à Windows Server 2008R2.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.