C语言发送邮件demo

2020-09-17  本文已影响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;
}
上一篇下一篇

猜你喜欢

热点阅读