IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Envoi de mail en langage C


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Août 2013
    Messages
    309
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2013
    Messages : 309
    Par défaut Envoi de mail en langage C
    Bonsoir, aimant par dessus tout me lancer des défis en langage C, je tente en ce moment de créer un petit programme d'envoi de mails. Le principe est d'utiliser les sockets pour se connecter au port 25 d'un serveur SMTP. D'autre part, j'utilise SDL pour avoir une interface graphique un peu plus confortable que la console, ce qui nécessite de créer des fonctions pour afficher les caractères ou pour effectuer des saisies.
    Mais bref le problème se situe plutôt du côté de la requête SMTP : J'arrive à me connecter sans problème, j'envoie alors les données au serveur SMTP : EHLO, FROM, TO, DATA ... et j'écris la réponse du serveur dans un fichier .txt à chaque fois. Mais lors des tests (J'essaie de m'envoyer un mail sur mon adresse gmail) après l'envoi du corps du message, le serveur me répond systématiquement "500 5.5.2 bad chars in command" et pas le moindre mail dans ma boîte de réception. J'ai revu la syntaxe de la requête dans tous les sens mais rien n'y fait, je suis complètement à court de solutions. Voici le code de mon programme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    int main(int argc,char *argv[])
    {
        srand(time(NULL));
        if(SDL_Init(SDL_INIT_VIDEO)!=0)     //Intro SDL
            return -1;
        SDL_Surface *ecran,*Fond,*caracteres[94],*messageConnexion,*CaracAdr[27],*Chiffres[10];
        SDL_Surface *MessageErreurConnex,*MessageOKConnex;
        SDL_Event event;
        SDL_Rect posFond,posErrConn,posOKConn;
        posFond.x=0;
        posFond.y=0;
        posErrConn.x=196;
        posErrConn.y=150;
        posOKConn.x=239;
        posOKConn.y=150;
     
        Uint16 choix,retourSaisie;
        char mailDest[50]="";
        char mailExp[50]="";
        char Objet[20]="";
        char Corps[TAILLECORPS]="";
        char ADR_SMTP[20]="";
        char Requete[1000]="";
        Uint32 tpsDebut,tpsActuel,chrono=0;
     
        WSADATA wsa;
        WSAStartup(MAKEWORD(2,2),&wsa);
     
        hostent *ip;
        sockaddr_in serv;
        SOCKET sock;
        int retour;
     
        SDL_WM_SetCaption("Envoi mails",NULL);       //Titre programme
        putenv("SDL_VIDEO_CENTERED=1");     	 //Fenêtre centrée
        ecran=SDL_SetVideoMode(800,600,32,SDL_HWSURFACE);       //Création fenêtre
     
        Fond=SDL_LoadBMP("Fond.bmp");
        messageConnexion=SDL_LoadBMP("messageConnexion.bmp");
        MessageOKConnex=SDL_LoadBMP("MessageOKConnex.bmp");
        MessageErreurConnex=SDL_LoadBMP("MessageErreurConnex.bmp");
     
        chargeCaracteres(caracteres,CaracAdr,Chiffres);           //Chargement des images caractères
     
        choix=Menu(ecran,caracteres);
        if(choix==1)        //L'utilisateur choisit de quitter le programme
        {
            SDL_Quit();
            return 0;
        }
        if(choix==0)	//L'utilisateur choisit d'envoyer un mail
        {
            retourSaisie=Saisie(ecran,Fond,caracteres,mailExp,mailDest,Objet,Corps,ADR_SMTP);
            if(retourSaisie==0)
            {
                SDL_Quit();
                return 0;
            }
        }
     
        SDL_BlitSurface(Fond,NULL,ecran,&posFond);       //Affichage message connexion
        afficheConnexion(ecran,messageConnexion,CaracAdr,ADR_SMTP);
        SDL_Flip(ecran);
     
        ip=gethostbyname(ADR_SMTP);
        sock=socket(PF_INET,SOCK_STREAM,0);     //Connexion au port 25 du serveur SMTP
        serv.sin_family=AF_INET;
        serv.sin_port=htons(25);
        memcpy(&serv.sin_addr,ip->h_addr,ip->h_length);
     
        retour=connect(sock,(struct sockaddr*)&serv,sizeof(serv));          //Connexion au serveur
        if(retour!=0)
        {
            SDL_BlitSurface(MessageErreurConnex,NULL,ecran,&posErrConn);
            SDL_Flip(ecran);
            return -2;
        }
        if(retour==0)
        {
            SDL_BlitSurface(MessageOKConnex,NULL,ecran,&posOKConn);
            SDL_Flip(ecran);
        }
     
        if(choix==0)
            RequeteSMTP(ecran,Fond,Requete,mailExp,mailDest,Objet,Corps,sock);   //Envoi mail
     
        SDL_Quit();
        return 0;
    }
    Voici le code de la fonction RequeteSMTP() :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    void RequeteSMTP(SDL_Surface *ecran,SDL_Surface *Fond,char *Requete,char *mailExp,char *mailDest,char *Objet,char *Corps,SOCKET sock)
    {
        char reponse[70]="";
        FILE *f=fopen("test.txt","a+");
     
        send(sock,"EHLO orange.fr\r\n",sizeof("EHLO orange.fr\r\n"),0);
        recv(sock,reponse,sizeof(reponse),0);
     
        sprintf(Requete,"MAIL FROM: <%s>\r\n",mailExp);
        send(sock,Requete,sizeof(Requete),0);
        recv(sock,reponse,sizeof(reponse),0);
     
        sprintf(Requete,"RCPT TO: <%s>\r\n",mailDest);
        send(sock,Requete,sizeof(Requete),0);
        recv(sock,reponse,sizeof(reponse),0);
     
        send(sock,"DATA\r\n",sizeof("DATA\r\n"),0);
        recv(sock,reponse,sizeof(reponse),0);
     
        sprintf(Requete,"Subject: %s\r\n%s\r\n.\r\n",Objet,Corps);
        send(sock,Requete,sizeof(Requete),0);
        recv(sock,reponse,sizeof(reponse),0);
        fprintf(f,"%s",reponse);			//Réponse enregistrée dans test.txt
     
        send(sock,"QUIT\r\n",sizeof("QUIT\r\n"),0);
        recv(sock,reponse,sizeof(reponse),0);
     
        fclose(f);
    }
    Voilà, je ne vois vraiment pas ce qui ne va pas. Il me semble bien que la syntaxe pour l'envoi du corps du message est bonne : L'objet du mail, un retour à la ligne, le message lui-même, un retour à la ligne, un point et un dernier retour à la ligne.

    Merci par avance à celui qui m'aidera.

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 476
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 476
    Par défaut
    Bonjour,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    send(sock,Requete,sizeof(Requete),0);
    Si tu écris cela, tu vas à chaque fois renvoyer la totalité du buffer, y compris, donc, ce qui ce trouve après la fin de chaîne et qui est complètement indéterminé. Utilise strlen() à la place de sizeof().

  3. #3
    Membre éclairé
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Août 2013
    Messages
    309
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2013
    Messages : 309
    Par défaut
    Merci pour la suggestion, je viens de tester ta solution mais en vain (Toujours la même réponse du serveur et pas de mail reçu). Tu penses que le programme envoie d'autres caractères en plus ? Parce que j'y ai déjà pensé et j'ai essayé de résoudre le problème en concaténant "\0" avec la chaîne.

    J'ai oublié de préciser que j'étais sous Windows 8 et Code::Blocks

  4. #4
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 476
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 476
    Par défaut
    En vrac :

    • Il faut utiliser strlen() lors de de tes send() et sizeof() lors de tes recv() ;
    • Dans la fonction principale de ton programme, tu appelles la routines d'envoi de mail mais toutes les chaînes sont vides. Tu as pensé à les remplir ?
    • Il faut attendre d'avoir reçu les réponses du serveur, effectivement, mais il faut également être sûr de les avoir reçues en entier. Elles peuvent nécessiter plusieurs recv() consécutifs, même si c'est peu probable en pratique ;
    • Si tu utilises EHLO, le serveur SMTP peut te renvoyer des réponses sur plusieurs lignes, auquel cas le code à trois chiffres est suivi de « - » pour indiquer qu'au moins une ligne doit encore suivre ;

  5. #5
    Membre éclairé
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Août 2013
    Messages
    309
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2013
    Messages : 309
    Par défaut
    Les chaînes sont remplies, c'est la fonction Saisie() qui s'en charge. Sinon je viens d'avoir une drôle de surprise : J'utilise une autre adresse mail comme adresse d'expéditeur, et je viens de voir dans la boîte mail correspondante 4 mails m'informant qu'un message n'avait pas pu être remis au destinataire, on peut au moins dire que c'est un progrès

  6. #6
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 476
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 476
    Par défaut
    Il faut que tu écrives à l'écran les réponses du serveur que tu reçois, puisque tu les récupères déjà avec recv().

    Sinon, il se peut que certains serveurs n'aiment pas les adresses mails entre chevrons « <…> » lors des commandes MAIL FROM: et RCPT TO: mais c'est peu probable ici.

Discussions similaires

  1. Envoi de mail au format html
    Par Mephyston dans le forum C++Builder
    Réponses: 2
    Dernier message: 22/01/2004, 12h29
  2. Envoi de mail au format Rich-Text
    Par LineLe dans le forum ASP
    Réponses: 4
    Dernier message: 29/10/2003, 16h27
  3. envoi de mail avec attachement de fichier
    Par GMI3 dans le forum Modules
    Réponses: 2
    Dernier message: 24/09/2003, 11h22
  4. Outlook ne se ferme pas après un envoi de mail
    Par Joke dans le forum VBA Access
    Réponses: 2
    Dernier message: 07/06/2003, 17h32
  5. envoi de mail, protocol SMTP langage C
    Par Heimdall dans le forum Développement
    Réponses: 2
    Dernier message: 23/05/2003, 11h22

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo