web-dev-qa-db-fra.com

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

J'utilise la bibliothèque SmtpClient pour envoyer des courriers électroniques à l'aide des é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 une variable SmtpException "Échec d'envoi de courrier." avec une IOException intérieure "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 jeter cette erreur.

83
Jake C

EDIT: Version Super Redux

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


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

.NET SmtpClientonly prend en charge le cryptage via STARTTLS. Si l'indicateur EnableSsl est défini, le serveur doit répondre à EHLO avec un STARTTLS, sinon il lève une exception. Voir la documentation MSDN pour plus de détails.

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

De retour dans la journée, lorsque les services voulaient également offrir le cryptage, ils se sont vu attribuer un numéro de port différent. Sur ce numéro de port, ils ont immédiatement établi une connexion SSL. Au fil du temps, ils ont compris qu'il était stupide de gaspiller deux numéros de port pour un seul service et ils ont conçu un moyen permettant aux services d'autoriser le texte en clair et le cryptage sur le même port à l'aide de STARTTLS. La communication commence par utiliser du texte en clair, puis utilise la commande STARTTLS pour effectuer une mise à niveau vers une connexion chiffrée. STARTTLS est devenu la norme pour le cryptage SMTP. Malheureusement, comme cela se produit toujours lors de l’implémentation d’une nouvelle norme, la compatibilité entre tous les clients et tous les serveurs existe.

Dans mon cas, mon utilisateur essayait de connecter le logiciel à un serveur qui imposait une connexion SSL immédiate, méthode héritée non prise en charge par Microsoft dans .NET.

150
Jake C

Changez le port de 465 à 587 et cela fonctionnera.

15
ADM-IT

Pour tous ceux qui tombent sur ce message à la recherche d'une solution et que vous avez configuré SMTP sendgrid 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, puis cliquez sur Gérer. Vous serez redirigé vers le site SendGrid.
  • Confirmez votre adresse e-mail, puis notez le nom d'utilisateur affiché. Il s'agit d'un nom d'utilisateur généré automatiquement. 
  • Ajoutez le nom d'utilisateur de SendGrid à vos paramètres SMTP dans le fichier web.config.

J'espère que cela t'aides!

13
nologo

Vous devrez peut-être également modifier le paramètre "Applications moins sécurisées" sur votre compte Gmail. EnableSsl, utilisez le port 587 et activez les "applications moins sécurisées". Si vous recherchez des applications moins sécurisées sur Google, des pages d’aide Google 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.

7
Bill Mahoney

Votre bibliothèque SMTP prend-elle en charge les connexions cryptées? Le serveur de messagerie attend peut-être une connexion TLS sécurisée et par conséquent la ferme en l'absence de prise de contact TLS

3
1234varun

Iv'e a essayé toutes les réponses ci-dessus mais j'ai toujours cette erreur avec un compte Office 365. Le code semble fonctionner correctement avec un compte Google et smtp.gmail.com lorsqu’il autorise 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 = "[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);
}

MISE À JOUR ET COMMENT JE L'AUR RÉSOLU:

Problème résolu en changeant Smtp Client en Mailkit. Le client System.Net.Mail Smtp n’est maintenant pas recommandé par Microsoft en raison de problèmes de sécurité et vous devriez plutôt utiliser MailKit. L'utilisation de Mailkit m'a permis de mieux comprendre les messages d'erreur que je pouvais comprendre pour trouver l'origine du problème (problème de licence). Vous pouvez obtenir Mailkit en le téléchargeant en tant que Nuget Package. 

Pour plus d’informations, lisez la documentation concernant Smtp Client: 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 = "[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);
        }
3
Martin Jaensson

Si vous utilisez un serveur SMTP sur la même boîte et que votre SMTP est lié à une adresse IP au lieu de "Toute affectation", il peut échouer car il tente d'utiliser une adresse IP (comme 127.0.0.1) avec laquelle SMTP ne fonctionne pas sur. 

2
flickerfly

Pour élever ce que jocull a mentionné dans un commentaire, je faisais tout ce qui était mentionné dans ce fil de discussion et je le faisais disparaître ... parce que le mien était en train de tourner en boucle; 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 inclut la création de SmtpClient, puis l’envoi. Avec les bonnes données. Le SmtpClient a été créé dans un bloc try/catch, afin d’attraper les erreurs et d’être sûr que l’objet a été détruit avant le bas de la boucle.

Dans mon cas, la solution consistait à s'assurer que SmtpClient était éliminé après chaque passage dans la boucle (via une instruction using () ou 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 tentative suivante.

1
Andy
//Try this out... Port 465 is not there anymore for use
     string emailFrom = "sender email here";
    string recieverEmail ="reciever email here";
            string subject = "subject here";
            string body = "message here";
            MailMessage maile = new MailMessage(emailFrom, recieverEmail, subject,body);
            SmtpClient client = new SmtpClient("smtp.gmail.com", 587);
            client.Credentials = new System.Net.NetworkCredential("senders gmail account username here", "senders gmail account password here");
            client.EnableSsl = true;
1
SelakaN

Au cas où toutes les solutions ci-dessus ne fonctionneraient pas pour vous, essayez de mettre à jour le fichier suivant sur votre serveur (par publier, et une construction antérieure serait utile).

bin-> projectname.dll 

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

1
Ajay Kumar

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
Hisham shahid

Changez votre numéro de port de 585 à 587

0
Abdus Salam Azad

Cette erreur est très générique. Cela peut être dû à plusieurs raisons telles que Le serveur de messagerie est incorrect . Certaines sociétés d'hébergement utilisent le format mail.domainname . Si vous utilisez uniquement 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="[email protected]">
        <!-- Uncomment to specify SMTP settings -->
        <network Host="domain.com" port="25" password="Jin@" userName="[email protected]"/>
      </smtp>
    </mailSettings>
0
Jin Thakur

Dans mon cas, le client a oublié d'ajouter une nouvelle adresse IP dans ses paramètres SMTP. Ouvrez IIS 6.0 sur le serveur qui configure le smtp, cliquez avec le bouton droit sur 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
Nora

Essayez ceci: Voici le code que j'utilise pour envoyer des emails à 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;
            }
        }
    }
0
yasmuru