美文网首页
C语言发送邮件demo

C语言发送邮件demo

作者: 贰爷 | 来源:发表于2020-09-17 22:56 被阅读0次
    #include <windows.h>
    #include <stdio.h>
    #include <WinSock.h>
    #include <iostream>
    using namespace std;
    #pragma  comment(lib, "ws2_32.lib")
     
    struct Base64Date6
    {
        unsigned int d4:6;
        unsigned int d3:6;
        unsigned int d2:6;
        unsigned int d1:6;
    };
    // 协议中加密部分使用的是baibase64方法
    char ConvertToBase64  (char   c6);
    void EncodeBase64     (char   *dbuf, char *buf128, int len);
    void SendMail         (char   *email,char *body);
    int  OpenSocket       (struct sockaddr *addr);
     
    int main()
    {
        char EmailTo[]         = "xushiladeng@qq.com";
        char EmailContents[]   = "From: \"lucy\"<xushiladeng@qq.com>\r\n"
            "To: \"dasiy\"<xushiladeng@qq.com>\r\n"
            "Subject: Hello\r\n\r\n"
            "Hello World, Hello Email!"
    //        "DATA\r\n" //告诉服务du器下面是邮件zhi
            //下面是邮件头
            "TO: xushiladeng@qq.com\r\n"
            "FROM: xushiladeng@qq.com\r\n"
            "SUBJECT: SMTP协议测试\r\n"
            "Date:2015-04-20\r\n"
            "X-Mailer:fice's mailer\r\n"
            "MIMI-Version:1.0\r\n"
            "Content-Type:multipart/mixed;boundary=\"#BOUNDARY#\"\r\n\r\n"//设置边界值,区分邮件内容的 两个回车换行
            "Content-Transfer-Encoding:7bit\r\n\r\n"
            "This is a multi-part message in MIME format\r\n\r\n"
            //发送邮件内容头部信息
            "--#BOUNDARY#\r\n"
            "Content-Type: text/plain;charset=gb2312\r\n"
            "Content-Transfer-Encoding:printable\r\n\r\n"
            //发送邮件的内容部分
            "SMTP协议测试:发送附件/n----by fice 2015.04.20\r\n"
            //发送附件头部信息
            "--#BOUNDARY#\r\n"
            "Content-Type:text/plain;name=student.txt\r\n"
            "Content-Transfer-Encoding:base64\r\n"
            "Content-Disposition:attachment;filename=\"test.txt\"\r\n\r\n";
        SendMail(EmailTo, EmailContents);
        return 0;
    }
     
    char ConvertToBase64(char uc)
    {
        if(uc < 26)
        {
            return 'A' + uc;
        }
        if(uc < 52)
        {
            return 'a' + (uc - 26);
        }
        if(uc < 62)
        {
            return '0' + (uc - 52);
        }
        if(uc == 62)
        {
            return '+';
        }
        return '/';
    }
     
    // base64的实现
    void EncodeBase64(char *dbuf, char *buf128, int len)
    {
        struct Base64Date6 *ddd      = NULL;
        int           i        = 0;
        char          buf[256] = {0};
        char          *tmp     = NULL;
        char          cc       = '\0';
     
        memset(buf, 0, 256);
        strcpy_s(buf, 256, buf128);
        for(i = 1; i <= len/3; i++)
        {
            tmp             = buf + (i-1)*3;
            cc              = tmp[2];
            tmp[2]          = tmp[0];
            tmp[0]          = cc;
            ddd             = (struct Base64Date6 *)tmp;
            dbuf[(i-1)*4+0] = ConvertToBase64((unsigned int)ddd->d1);
            dbuf[(i-1)*4+1] = ConvertToBase64((unsigned int)ddd->d2);
            dbuf[(i-1)*4+2] = ConvertToBase64((unsigned int)ddd->d3);
            dbuf[(i-1)*4+3] = ConvertToBase64((unsigned int)ddd->d4);
        }
        if(len % 3 == 1)
        {
            tmp             = buf + (i-1)*3;
            cc              = tmp[2];
            tmp[2]          = tmp[0];
            tmp[0]          = cc;
            ddd             = (struct Base64Date6 *)tmp;
            dbuf[(i-1)*4+0] = ConvertToBase64((unsigned int)ddd->d1);
            dbuf[(i-1)*4+1] = ConvertToBase64((unsigned int)ddd->d2);
            dbuf[(i-1)*4+2] = '=';
            dbuf[(i-1)*4+3] = '=';
        }
        if(len%3 == 2)
        {
            tmp             = buf+(i-1)*3;
            cc              = tmp[2];
            tmp[2]          = tmp[0];
            tmp[0]          = cc;
            ddd             = (struct Base64Date6 *)tmp;
            dbuf[(i-1)*4+0] = ConvertToBase64((unsigned int)ddd->d1);
            dbuf[(i-1)*4+1] = ConvertToBase64((unsigned int)ddd->d2);
            dbuf[(i-1)*4+2] = ConvertToBase64((unsigned int)ddd->d3);
            dbuf[(i-1)*4+3] = '=';
        }
        return;
    }
    // 发送邮件
    void SendMail(char *email, char *body)
    {
        int     sockfd     = {0};
        char    buf[1500]  = {0};
        char    rbuf[1500] = {0};
        char    login[128] = {0};
        char    pass[128]  = {0};
        WSADATA WSAData;
        struct sockaddr_in their_addr = {0};
        WSAStartup(MAKEWORD(2, 2), &WSAData);
        memset(&their_addr, 0, sizeof(their_addr));
     
        their_addr.sin_family = AF_INET;
        their_addr.sin_port   = htons(25);
        hostent* hptr         = gethostbyname("smtp.126.com"); 
        memcpy(&their_addr.sin_addr.S_un.S_addr, hptr->h_addr_list[0], hptr->h_length); 
        printf("IP of smpt.126.com is : %d:%d:%d:%d\n", 
            their_addr.sin_addr.S_un.S_un_b.s_b1, 
            their_addr.sin_addr.S_un.S_un_b.s_b2, 
            their_addr.sin_addr.S_un.S_un_b.s_b3, 
            their_addr.sin_addr.S_un.S_un_b.s_b4); 
     
        // 连接邮件服务器,如果连接后没有响应,则2 秒后重新连接
        sockfd = OpenSocket((struct sockaddr *)&their_addr);
        memset(rbuf, 0, 1500);
        while(recv(sockfd, rbuf, 1500, 0) == 0)
        {
            cout<<"reconnect..."<<endl;
            Sleep(2);
            sockfd = OpenSocket((struct sockaddr *)&their_addr);
            memset(rbuf, 0, 1500);
        }
     
        cout<<rbuf<<endl;
     
        // EHLO
        memset(buf, 0, 1500);
        sprintf_s(buf, 1500, "EHLO HYL-PC\r\n");
        send(sockfd, buf, strlen(buf), 0);
        memset(rbuf, 0, 1500);
        recv(sockfd, rbuf, 1500, 0);
        cout<<"EHLO REceive: "<<rbuf<<endl;
     
        // AUTH LOGIN
        memset(buf, 0, 1500);
        sprintf_s(buf, 1500, "AUTH LOGIN\r\n");
        send(sockfd, buf, strlen(buf), 0);
        memset(rbuf, 0, 1500);
        recv(sockfd, rbuf, 1500, 0);
        cout<<"Auth Login Receive: "<<rbuf<<endl;
     
        // USER
        memset(buf, 0, 1500);
        sprintf_s(buf, 1500, "xushiladeng@qq.com");//你的邮箱账号
        memset(login, 0, 128);
        EncodeBase64(login, buf, strlen(buf));
        sprintf_s(buf, 1500, "%s\r\n", login);
        send(sockfd, buf, strlen(buf), 0);
        cout<<"Base64 UserName: "<<buf<<endl;
        memset(rbuf, 0, 1500);
        recv(sockfd, rbuf, 1500, 0);
        cout<<"User Login Receive: "<<rbuf<<endl;
     
        // PASSWORD
        sprintf_s(buf, 1500, "********");//你的邮箱密码
        memset(pass, 0, 128);
        EncodeBase64(pass, buf, strlen(buf));
        sprintf_s(buf, 1500, "%s\r\n", pass);
        send(sockfd, buf, strlen(buf), 0);
        cout<<"Base64 Password: "<<buf<<endl;
     
        memset(rbuf, 0, 1500);
        recv(sockfd, rbuf, 1500, 0);
        cout<<"Send Password Receive: "<<rbuf<<endl;
     
        // MAIL FROM
        memset(buf, 0, 1500);
        sprintf_s(buf, 1500, "MAIL FROM: <xushiladeng@qq.com>\r\n");
        send(sockfd, buf, strlen(buf), 0);
        memset(rbuf, 0, 1500);
        recv(sockfd, rbuf, 1500, 0);
        cout<<"set Mail From Receive: "<<rbuf<<endl;
     
        // RCPT TO 第一个收件人
        sprintf_s(buf, 1500, "RCPT TO:<%s>\r\n", email);
        send(sockfd, buf, strlen(buf), 0);
        memset(rbuf, 0, 1500);
        recv(sockfd, rbuf, 1500, 0);
        cout<<"Tell Sendto Receive: "<<rbuf<<endl;
     
        // DATA 准备开始发送邮件内容
        sprintf_s(buf, 1500, "DATA\r\n");
        send(sockfd, buf, strlen(buf), 0);
        memset(rbuf, 0, 1500);
        recv(sockfd, rbuf, 1500, 0);
        cout<<"Send Mail Prepare Receive: "<<rbuf<<endl;
     
        // 发送邮件内容,\r\n.\r\n内容结束标记
        sprintf_s(buf, 1500, "%s\r\n.\r\n", body);
        send(sockfd, buf, strlen(buf), 0);//发送邮件,不带附件的内容
     
        //用二进制方式读取附件文件内容并转为base64格式  
        FILE* pf = fopen("D:\\test.txt","rb");
        fseek(pf,0,SEEK_END);
        int filelen = ftell(pf);
        char* filebuf = (char*) malloc(filelen);
        char* filebase64 = (char*) malloc(filelen*2);
        memset(filebase64,0,filelen*2);
        fseek(pf,0,SEEK_SET);
        fread(filebuf,1,filelen,pf);  
        EncodeBase64(filebase64,filebuf,filelen); 
     
        send(sockfd, filebase64, strlen(filebase64), 0);//发送邮件的内容
        memset(rbuf, 0, 1500);
        recv(sockfd, rbuf, 1500, 0);
        cout<<"Send Mail Receive: "<<rbuf<<endl;
     
        // QUIT
        sprintf_s(buf, 1500, "QUIT\r\n");
        send(sockfd, buf, strlen(buf), 0);
        memset(rbuf, 0, 1500);
        recv(sockfd, rbuf, 1500, 0);
        cout<<"Quit Receive: "<<rbuf<<endl;
     
        //清理工作
        closesocket(sockfd);
        WSACleanup();
        return;
    }
    // 打开TCP Socket连接
    int OpenSocket(struct sockaddr *addr)
    {
        int sockfd = 0;
        sockfd=socket(PF_INET, SOCK_STREAM, 0);
        if(sockfd < 0)
        {
            cout<<"Open sockfd(TCP) error!"<<endl;
            exit(-1);
        }
        if(connect(sockfd, addr, sizeof(struct sockaddr)) < 0)
        {
            cout<<"Connect sockfd(TCP) error!"<<endl;
            exit(-1);
        }
        return sockfd;
    }
    

    相关文章

      网友评论

          本文标题:C语言发送邮件demo

          本文链接:https://www.haomeiwen.com/subject/wftdyktx.html