Envoi de mail : dépassement du délai

Résolu
MGD Software Messages postés 186 Date d'inscription vendredi 1 septembre 2006 Statut Membre Dernière intervention 23 avril 2022 - 26 mars 2019 à 12:24
MGD Software Messages postés 186 Date d'inscription vendredi 1 septembre 2006 Statut Membre Dernière intervention 23 avril 2022 - 1 avril 2019 à 10:24
Bonjour,
Après avoir écumé les forums les plus divers, je n'arrive toujours pas à envoyer un mail depuis que tous les fournisseurs d'accès chez qui j'ai un compte ont imposé le SMTP authentifié.
Comme j'ai plus de 25 boites à lettres, j'ai essayé au moins une adresse chez Free, SFR, Gmail, Hostinger, Online, toujours sans résultats.

Le diagnostic est toujours le même : délai de connexion dépassé.

Je précise que les informations de connexion fonctionnent parfaitement avec Outlook.

Je joins le code de la fonction qui envoie le mail. Ce mail est envoyé par cette appli sur mon serveur local à chaque changement d'IP (elle est dynamique, hélas). Enfin, quand ça marche...

Quelques précisions :

- La classe ProfileString reproduit l'ancien fonctionnement des fonctions homonymes chères à Windows 95 et me permet de stocker facilement des paramètres hors de la base de registre (le fameux fichier ".ini") et à l'endroit que JE souhaite.

- les paramètres SMTP authentifié ont été vérifiés. De plus, pour Gmail, le mot de passe est un mot de passe d'application, spécifique pour les applications "non sécurisées" (Google dixit). En règle générale, le port utilisé est le 465, et le SSL est activé. Le serveur est smtp.xxx (smtp.free.fr, smtp.sfr.fr, smtp.gmail.com, mx1.hostinget.fr, smtp.hostinger.fr, smtp.online.net, etc.).

- Les destinataires peuvent être plusieurs, ce qui explique la boucle dans le tableau Dests. Ces destinataires peuvent être ou non validés.

- Le corps du message est un texte modèle comportant des marqueurs, remplacés par leur valeur lors de l'envoi du mail.

voici le code de la fonction :
private bool SendIP()
{
    SmtpClient Client = new SmtpClient();
    MailMessage Mail = new MailMessage();
    try
    {
        // Paramètres de connexion
        Client.Host = ProfileString.GetIniParam("Options", "EmailHost", "");
        Client.Port = (int)ProfileString.GetIniParam("Options", "EmailPort", 0);
        Client.EnableSsl = ProfileString.GetIniParam("Options", "EmailSSL", true);
        Client.DeliveryMethod = SmtpDeliveryMethod.Network;
        Client.Timeout = 30000;       // 30 secondes par défaut
        string User = ProfileString.GetIniParam("Options", "EmailUser", "");
        string Pwd = Crypt.CryptOff(ProfileString.GetIniParam("Options", "EmailPwd", ""), CrypKey);
        if (User != "" || Pwd != "")
        {
            Client.UseDefaultCredentials = false;
            //Client.UseDefaultCredentials = true;
            Client.Credentials = new NetworkCredential(User, Pwd);
        }
        else
            Client.UseDefaultCredentials = true;

        Mail.BodyEncoding = UTF8Encoding.UTF8;
        Mail.DeliveryNotificationOptions = DeliveryNotificationOptions.OnFailure;

        // Adresse origine
        string FromAdrs = ProfileString.GetIniParam("Options", "EamilFromAdrs", "");
        string FromName = ProfileString.GetIniParam("Options", "EmailFromName", "");
        Mail.From = new MailAddress(FromAdrs, FromName);
        Mail.Sender = new MailAddress(FromAdrs, FromName);

        // Destinataires
        string[] Dests = ProfileString.GetIniParamsList("Emails");
        string DefMails = "";
        foreach (string Dest in Dests)
        {
            string[] Dummy = ProfileString.GetIniParam("Emails", Dest, "").Split('|');
            string MailAdrs = Dummy[0];
            bool Enabled = false;
            if (Dummy.Length > 1)
                Enabled = Dummy[1] == "1";
            if (Enabled )
            {
                if (IsValidMail(MailAdrs))
                    Mail.To.Add(MailAdrs);
                else
                    DefMails += "\n" + MailAdrs;
            }
        }

        // Sujet et corps
        string Body = MgdDiv.Base64Decode(ProfileString.GetIniParam("Options", "EmailText", ""));
        Body = Body.Replace("[$IP$]", lblIpAddress.Text);
        Body = Body.Replace("[$DATE$]", DateTime.Now.ToShortDateString());
        Body = Body.Replace("[$TIME$]", DateTime.Now.ToLongTimeString());
        Mail.Subject = ProfileString.GetIniParam("Options", "EmailSubject", "");
        Mail.Body = Body;

        // Armement du timer de rappel en cas d'exception lors de l'envoi
        lblLastTrans.Text = "";
        tmrSend.Enabled = true;

        // Envoi du message
        this.Cursor = Cursors.WaitCursor;
        Client.Send(Mail);
        tmrSend.Enabled = false;        // Envoi ok : on annule le renvoi
        this.Cursor = Cursors.Default;
        lblLastTrans.Text = DateTime.Now.ToString("G");
        if (DefMails != "")
        {
            string Prompt = "Les destinataires suivants présentent une erreur : " + DefMails;
            if (this.Visible)
                MessageBox.Show(Prompt, "Envoi de mail", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
        return true;
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message, "Erreur d'envoi", MessageBoxButtons.OK, MessageBoxIcon.Error);
        this.Cursor = Cursors.Default;
        return false;
    }
}


La gestion de l'utilisateur et du mot de passe est-elle correcte ? (j'ai un doute concernant le Client.UseDefaultCredentials, la doc Microsoft n'est pas du tout claire là-dessus). Mais j'ai essayé true et false, et le résultat est le même.

Est-ce que j'aurais oublié un paramètre ??

Est-il possible d'avoir un diagnostic plus précis que le "délai dépassé" ? J'ai cherché dans les propriétés de Client et de Mail dans le traitement de l'exception, mais rien d'autre que le message d'erreur lui-même ("Le délai d'attente de l'opération a expiré."), ou le status de l'exception "General failure".

2 réponses

ThePearl98 Messages postés 1 Date d'inscription lundi 1 avril 2019 Statut Membre Dernière intervention 1 avril 2019
1 avril 2019 à 01:19
Salut Mr.
J'utilises Ubuntu 18 LTS , j'ai essayé ton code sur V_MACHINE Windows 7, VS 2008 .NET 2.0 en utilisant Tcl et j'ai toujours ce message immédiatement :
 Unhandled Exception: System.Net.Mail.SmtpException: The operation has timed out
   at Exception.Handle :line 29


J'ai ajouté
1.nouvelle variable pour l utiliser en Bloc Try :
var task = Task.Factory.StartNew(() => SendEmail(email));

if (!task.Wait(6000))
   // error handling for timeout on TCP layer (but you don't get the exception object)

2. un 2éme bloc catch :
using (var client = new SmtpClient(_serverCfg.Host, _serverCfg.Port)) 
{        
    try
    {
        client.Timeout = 5000;   // shorter timeout than the task.Wait()
        // ...
        client.Send(msg);
    }
    catch (Exception ex)
    {
        // exception handling
    }
}
0
MGD Software Messages postés 186 Date d'inscription vendredi 1 septembre 2006 Statut Membre Dernière intervention 23 avril 2022 2
Modifié le 1 avril 2019 à 10:28
Bonjour,
Cette exception de timeout est bien le cœur du problème.
Pour ma part, elle est traitée au niveau supérieur, dans la fonction appelante.

Après de multiples essais, j'ai enfin réussi une connexion sur le serveur de Gmail, en validant la double authentification, en utilisant un mot de passe "application" et le port 587 en SSL.

Donc à priori le problème ne provient pas du code : s'il marche pour un serveur, il devrait fonctionner pour les autres. J'ai pourtant vérifié tous les paramètres de ces derniers. Et même Gmail, avec le mot de passe standard de messagerie, ne fonctionne pas alors que ça marche avec Outlook à partir de la même IP (mais pas du même poste).

Il est possible qu'avec la paranoïa actuelle des serveurs de messagerie, il y ait un contrôle du contenu des messages et que le serveur détecte si le mail provient d'une machine et non d'un logiciel de messagerie. Ce qui voudrait dire que ces derniers formatent le message de façon spécifique. Je n'ai rien trouvé à ce sujet sur la toile, mais peut-être que j'ai trop d'imagination.

En attendant, mon appli fonctionne mais c'est quand même bizarre que les serveurs ne répondent pas, quitte à envoyer un message de rejet.
0
Rejoignez-nous