• C++发送邮件和附件


     

     头文件

    [cpp] view plaincopy
     
    1. /*********************************************************************** 
    2. *发送邮件模块头文件 
    3. *可以发送文本和附件(支持多个附件一起发送) 
    4. *************************************************************************/  
    5. #pragma once  
    6. struct sMailInfo //邮件信息  
    7. {  
    8.     char*   m_pcUserName;//用户登录邮箱的名称  
    9.     char*   m_pcUserPassWord;//用户登录邮箱的密码  
    10.     char*   m_pcSenderName;//用户发送时显示的名称  
    11.     char*   m_pcSender;//发送者的邮箱地址  
    12.     char*   m_pcReceiver;//接收者的邮箱地址  
    13.     char*   m_pcTitle;//邮箱标题  
    14.     char*   m_pcBody;//邮件文本正文  
    15.     char*   m_pcIPAddr;//服务器的IP  
    16.     char*   m_pcIPName;//服务器的名称(IP与名称二选一,优先取名称)  
    17.     sMailInfo(){memset(this,0,sizeof(sMailInfo));}  
    18. };  
    19. class CSendMail  
    20. {  
    21. public:  
    22.     CSendMail(void);  
    23.     ~CSendMail(void);  
    24.   
    25. public:  
    26.     bool SendMail(sMailInfo &smailInfo);//发送邮件,需要在发送的时候初始化邮件信息  
    27.     void AddFilePath(char * pcFilePath);//添加附件的决定路径到附件列表中  
    28.     void DeleteFilePath(char* pcFilePath);//删除附件路径,如果有的话  
    29.     void DeleteAllPath(void);//删除全部附件的路径  
    30.   
    31. protected:  
    32.     void GetFileName(char* fileName,char* filePath);//从附件的路径中获取文件名称  
    33.     void Char2Base64(char* pBuff64,char* pSrcBuff,int iLen);//把char类型转换成Base64类型  
    34.     bool  CReateSocket(SOCKET &sock);//建立socket连接  
    35.     bool Logon(SOCKET &sock);//登录邮箱,主要进行发邮件前的准备工作  
    36.     int GetFileData(char* FilePath);//由文件路径获取附件内容  
    37.   
    38.     bool SendHead(SOCKET &sock);//发送邮件头  
    39.     bool SendTextBody(SOCKET &sock);//发送邮件文本正文  
    40.     bool SendFileBody(SOCKET &sock);//发送邮件附件  
    41.     bool SendEnd(SOCKET &sock);//发送邮件结尾  
    42. protected:  
    43.     CList<char*,char*> m_pcFilePathList;//记录附件路径  
    44.   
    45.     char  m_cSendBuff[4096];//发送缓冲区  
    46.     char  m_cReceiveBuff[1024];  
    47.     char* m_pcFileBuff;//指向附件内容  
    48.     sMailInfo m_sMailInfo;  
    49. };  


    模块实现文件

    [cpp] view plaincopy
     
    1. /************************************************************************ 
    2. * 发送邮件模块 
    3. *可以发送文本和附件(支持多个附件一起发送) 
    4. *Date:2011-12-01 
    5. ************************************************************************/  
    6. #include "StdAfx.h"  
    7. #include "SendMail.h"  
    8. #include "winsock2.h"  
    9. #pragma comment(lib,"WSOCK32")  
    10.   
    11. CSendMail::CSendMail(void)  
    12. {  
    13.     m_pcFileBuff=NULL;  
    14.     memset(m_cSendBuff,0,sizeof(m_cSendBuff));  
    15.     memset(m_cReceiveBuff,0,sizeof(m_cReceiveBuff));  
    16. }  
    17.   
    18.   
    19. CSendMail::~CSendMail(void)  
    20. {  
    21.     DeleteAllPath();  
    22. }  
    23.   
    24.   
    25. void CSendMail::Char2Base64(char* pBuff64,char* pSrcBuff,int iLen)  
    26. {  
    27.     //1   1   1   1   1   1   1   1  
    28.     // 分配给pBuff64  ↑ 分配给pBuff64+1  
    29.     //         point所在的位置  
    30.     static char Base64Encode[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";//base64所映射的字符表  
    31.     int point;//每一个源字符拆分的位置,可取2,4,6;初始为2  
    32.     point=2;  
    33.     int i;  
    34.     int iIndex;//base64字符的索引  
    35.     char n=0;//上一个源字符的残留值  
    36.     for(i=0;i<iLen;i++)  
    37.     {  
    38.         if(point==2)  
    39.         {  
    40.             iIndex=((*pSrcBuff)>>point)&0x3f;//取得pSrcBuff的高point位  
    41.         }  
    42.         else if (point==4)  
    43.         {  
    44.             iIndex=((*pSrcBuff)>>point)&0xf;//取得pSrcBuff的高point位  
    45.         }  
    46.         else if(point==6)  
    47.         {  
    48.             iIndex=((*pSrcBuff)>>point)&0x3;//取得pSrcBuff的高point位  
    49.         }  
    50.         iIndex+=n;//与pSrcBuff-1的低point结合组成Base64的索引  
    51.         *pBuff64++=Base64Encode[iIndex];//由索引表得到pBuff64  
    52.         n=((*pSrcBuff)<<(6-point));//计算源字符中的残留值  
    53.         n=n&0x3f;//确保n的最高两位为0  
    54.         point+=2;//源字符的拆分位置上升2  
    55.         if(point==8)//如果拆分位置为8说明pSrcBuff有6位残留,可以组成一个完整的Base64字符,所以直接再组合一次  
    56.         {  
    57.             iIndex=(*pSrcBuff)&0x3f;//提取低6位,这就是索引了  
    58.             *pBuff64++=Base64Encode[iIndex];//  
    59.             n=0;//残留值为0  
    60.             point=2;//拆分位置设为2  
    61.         }  
    62.         pSrcBuff++;  
    63.   
    64.     }  
    65.     if(n!=0)  
    66.     {  
    67.         *pBuff64++=Base64Encode[n];  
    68.     }  
    69.     if(iLen%3==2)//如果源字符串长度不是3的倍数要用'='补全  
    70.     {  
    71.         *pBuff64='=';  
    72.     }  
    73.     else if(iLen%3==1)  
    74.     {  
    75.         *pBuff64++='=';  
    76.         *pBuff64='=';  
    77.     }  
    78. }  
    79.   
    80. void CSendMail::AddFilePath(char * pcFilePath)//添加附件路径  
    81. {  
    82.     if(pcFilePath==NULL)  
    83.     {  
    84.         return;  
    85.     }  
    86.     int i;  
    87.     char* temp;  
    88.     for(i=0;i<m_pcFilePathList.GetCount();i++)  
    89.     {  
    90.         temp=m_pcFilePathList.GetAt(m_pcFilePathList.FindIndex(i));  
    91.         if(strcmp(pcFilePath,temp)==0)//如果已经存在就不用再添加了  
    92.         {  
    93.             return;  
    94.         }  
    95.     }  
    96.     m_pcFilePathList.AddTail(pcFilePath);  
    97. }  
    98.   
    99. void CSendMail::DeleteFilePath(char* pcFilePath)//删除附件路径  
    100. {  
    101.     int i;  
    102.     char* temp;  
    103.     for(i=0;i<m_pcFilePathList.GetCount();i++)  
    104.     {  
    105.         temp=m_pcFilePathList.GetAt(m_pcFilePathList.FindIndex(i));  
    106.         if(strcmp(temp,pcFilePath)==0)//找到并删除它,如果没找到就算了  
    107.         {  
    108.             m_pcFilePathList.RemoveAt(m_pcFilePathList.FindIndex(i));  
    109.             delete[] temp;  
    110.             return;  
    111.         }  
    112.     }  
    113. }  
    114.   
    115.   
    116. void CSendMail::DeleteAllPath(void)  
    117. {  
    118.     m_pcFilePathList.RemoveAll();  
    119. }  
    120.   
    121. int CSendMail::GetFileData(char* FilePath)  
    122. {  
    123.     m_pcFileBuff=NULL;  
    124.     if(FilePath==NULL)  
    125.     {  
    126.         return 0;  
    127.     }  
    128.     CFile f;  
    129.     int len;  
    130.       
    131.       
    132.     USES_CONVERSION;  
    133.     if(!f.Open(A2W(FilePath),CFile::modeRead|CFile::modeNoTruncate|CFile::typeBinary))  
    134.     {  
    135.         return 0;  
    136.     }  
    137.     len=(int)f.GetLength();  
    138.     m_pcFileBuff=new char[len+1];  
    139.     memset(m_pcFileBuff,0,len+1);  
    140.     f.Read(m_pcFileBuff,len);  
    141.   
    142.     f.Close();  
    143.     return len;  
    144. }  
    145.   
    146. void CSendMail::GetFileName(char* fileName,char* filePath)  
    147. {  
    148.     if(filePath==NULL || fileName==NULL)  
    149.     {  
    150.         return;  
    151.     }  
    152.     int i;  
    153.     for(i=0;i<(int)strlen(filePath);i++)  
    154.     {  
    155.         if(filePath[strlen(filePath)-1-i]=='\')  
    156.         {  
    157.             memcpy(fileName,&filePath[strlen(filePath)-i],i);  
    158.             return;  
    159.         }  
    160.     }  
    161. }  
    162.   
    163. bool CSendMail::CReateSocket(SOCKET &sock)  
    164. {  
    165.     WORD wVersionRequested;  
    166.     WSADATA wsaData;  
    167.     int err;  
    168.     wVersionRequested = MAKEWORD( 2, 2 );  
    169.     err = WSAStartup( wVersionRequested, &wsaData );  
    170.     if ( err != 0 )   
    171.     {  
    172.         return false;  
    173.     }  
    174.     if ( LOBYTE( wsaData.wVersion ) != 2 ||  
    175.         HIBYTE( wsaData.wVersion ) != 2 )  
    176.     {  
    177.         WSACleanup( );  
    178.         return false;   
    179.     }  
    180.     sock = socket(AF_INET,SOCK_STREAM,IPPROTO_IP);  
    181.     if (sock == INVALID_SOCKET)  
    182.     {  
    183.         return false;  
    184.     }  
    185.   
    186.     sockaddr_in servaddr;  
    187.     memset(&servaddr,0,sizeof(sockaddr_in));  
    188.     servaddr.sin_family = AF_INET;  
    189.     servaddr.sin_port = htons(25);//发邮件一般都是25端口  
    190.     if(m_sMailInfo.m_pcIPName=="")  
    191.     {  
    192.         servaddr.sin_addr.s_addr = inet_addr(m_sMailInfo.m_pcIPAddr);//直接使用IP地址  
    193.     }  
    194.     else  
    195.     {  
    196.         struct hostent *hp=gethostbyname(m_sMailInfo.m_pcIPName);//使用名称  
    197.         servaddr.sin_addr.s_addr=*(int*)(*hp->h_addr_list);  
    198.     }  
    199.   
    200.   
    201.     int ret = connect(sock,(sockaddr*)&servaddr,sizeof(servaddr));//建立连接  
    202.     if (ret == SOCKET_ERROR)  
    203.     {  
    204.         return false;  
    205.     }  
    206.   
    207.     return true;  
    208. }  
    209.   
    210.   
    211. bool CSendMail::Logon(SOCKET &sock)  
    212. {  
    213.     recv(sock,m_cReceiveBuff,1024,0);  
    214.   
    215.     memset(m_cSendBuff,0,sizeof(m_cSendBuff));  
    216.     sprintf_s(m_cSendBuff,"HELO [] ");  
    217.     send(sock,m_cSendBuff,strlen(m_cSendBuff),0);//开始会话  
    218.     recv(sock,m_cReceiveBuff,1024,0);  
    219.     if(m_cReceiveBuff[0]!='2' || m_cReceiveBuff[1]!='5' || m_cReceiveBuff[2]!='0')  
    220.     {  
    221.         return false;  
    222.     }  
    223.   
    224.     memset(m_cSendBuff,0,sizeof(m_cSendBuff));  
    225.     sprintf_s(m_cSendBuff,"AUTH LOGIN ");  
    226.     send(sock,m_cSendBuff,strlen(m_cSendBuff),0);//请求登录  
    227.     recv(sock,m_cReceiveBuff,1024,0);  
    228.     if(m_cReceiveBuff[0]!='3' || m_cReceiveBuff[1]!='3' || m_cReceiveBuff[2]!='4')  
    229.     {  
    230.         return false;  
    231.     }  
    232.   
    233.     memset(m_cSendBuff,0,sizeof(m_cSendBuff));  
    234.     Char2Base64(m_cSendBuff,m_sMailInfo.m_pcUserName,strlen(m_sMailInfo.m_pcUserName));  
    235.     m_cSendBuff[strlen(m_cSendBuff)]=' ';  
    236.     m_cSendBuff[strlen(m_cSendBuff)]=' ';  
    237.     send(sock,m_cSendBuff,strlen(m_cSendBuff),0);//发送用户名  
    238.     recv(sock,m_cReceiveBuff,1024,0);  
    239.     if(m_cReceiveBuff[0]!='3' || m_cReceiveBuff[1]!='3' || m_cReceiveBuff[2]!='4')  
    240.     {  
    241.         return false;  
    242.     }  
    243.   
    244.     memset(m_cSendBuff,0,sizeof(m_cSendBuff));  
    245.     Char2Base64(m_cSendBuff,m_sMailInfo.m_pcUserPassWord,strlen(m_sMailInfo.m_pcUserPassWord));  
    246.     m_cSendBuff[strlen(m_cSendBuff)]=' ';  
    247.     m_cSendBuff[strlen(m_cSendBuff)]=' ';  
    248.     send(sock,m_cSendBuff,strlen(m_cSendBuff),0);//发送用户密码  
    249.     recv(sock,m_cReceiveBuff,1024,0);  
    250.     if(m_cReceiveBuff[0]!='2' || m_cReceiveBuff[1]!='3' || m_cReceiveBuff[2]!='5')  
    251.     {  
    252.         return false;  
    253.     }  
    254.     return true;//登录成功  
    255. }  
    256.   
    257.   
    258. bool CSendMail::SendHead(SOCKET &sock)  
    259. {  
    260.     int rt;  
    261.     memset(m_cSendBuff,0,sizeof(m_cSendBuff));  
    262.     sprintf_s(m_cSendBuff,"MAIL FROM:<%s> ",m_sMailInfo.m_pcSender);  
    263.     rt=send(sock,m_cSendBuff,strlen(m_cSendBuff),0);  
    264.       
    265.     if(rt!=strlen(m_cSendBuff))  
    266.     {  
    267.         return false;  
    268.     }  
    269.     recv(sock,m_cReceiveBuff,1024,0);  
    270.   
    271.     memset(m_cSendBuff,0,sizeof(m_cSendBuff));  
    272.     sprintf_s(m_cSendBuff,"RCPT TO:<%s> ",m_sMailInfo.m_pcReceiver);  
    273.     rt=send(sock,m_cSendBuff,strlen(m_cSendBuff),0);  
    274.     if(rt!=strlen(m_cSendBuff))  
    275.     {  
    276.         return false;  
    277.     }  
    278.     recv(sock,m_cReceiveBuff,1024,0);  
    279.   
    280.     memset(m_cSendBuff,0,sizeof(m_cSendBuff));  
    281.     memcpy(m_cSendBuff,"DATA ",strlen("DATA "));  
    282.     rt=send(sock,m_cSendBuff,strlen(m_cSendBuff),0);  
    283.     if(rt!=strlen(m_cSendBuff))  
    284.     {  
    285.         return false;  
    286.     }  
    287.     recv(sock,m_cReceiveBuff,1024,0);  
    288.   
    289.     memset(m_cSendBuff,0,sizeof(m_cSendBuff));  
    290.     sprintf_s(m_cSendBuff,"From:"%s"<%s> ",m_sMailInfo.m_pcSenderName,m_sMailInfo.m_pcSender);  
    291.     sprintf_s(&m_cSendBuff[strlen(m_cSendBuff)],150,"To:"INVT.COM.CN"<%s> ",m_sMailInfo.m_pcReceiver);  
    292.     sprintf_s(&m_cSendBuff[strlen(m_cSendBuff)],150,"Subject:%s Mime-Version: 1.0 Content-Type: multipart/mixed;   boundary="INVT" ",m_sMailInfo.m_pcTitle);  
    293.     rt=send(sock,m_cSendBuff,strlen(m_cSendBuff),0);  
    294.     if(rt!=strlen(m_cSendBuff))  
    295.     {  
    296.         return false;  
    297.     }  
    298.   
    299.     return true;  
    300. }  
    301.   
    302. bool CSendMail::SendTextBody(SOCKET &sock)  
    303. {  
    304.     int rt;  
    305.     memset(m_cSendBuff,0,sizeof(m_cSendBuff));  
    306.     sprintf_s(m_cSendBuff,"--INVT Content-Type: text/plain;   charset="gb2312" %s ",m_sMailInfo.m_pcBody);  
    307.     rt=send(sock,m_cSendBuff,strlen(m_cSendBuff),0);  
    308.     if(rt!=strlen(m_cSendBuff))  
    309.     {  
    310.         return false;  
    311.     }  
    312.     else  
    313.     {  
    314.         return true;  
    315.     }  
    316. }  
    317.   
    318. bool CSendMail::SendFileBody(SOCKET &sock)  
    319. {  
    320.     int i;  
    321.     char* filePath;  
    322.     int rt;  
    323.     int len;  
    324.     int pt=0;  
    325.     char fileName[128];  
    326.     for(i=0;i<m_pcFilePathList.GetCount();i++)  
    327.     {  
    328.         pt=0;  
    329.         memset(fileName,0,128);  
    330.         filePath=m_pcFilePathList.GetAt(m_pcFilePathList.FindIndex(i));  
    331.         len=GetFileData(filePath);  
    332.         GetFileName(fileName,filePath);  
    333.   
    334.         sprintf_s(m_cSendBuff,"--INVT Content-Type: application/octet-stream;   name="%s" Content-Transfer-Encoding: base64 Content-Disposition: attachment;   filename="%s" ",fileName,fileName);  
    335.         send(sock,m_cSendBuff,strlen(m_cSendBuff),0);  
    336.         while (pt<len)  
    337.         {  
    338.             memset(m_cSendBuff,0,sizeof(m_cSendBuff));  
    339.             Char2Base64(m_cSendBuff,&m_pcFileBuff[pt],min(len-pt,3000));  
    340.             m_cSendBuff[strlen(m_cSendBuff)]=' ';  
    341.             m_cSendBuff[strlen(m_cSendBuff)]=' ';  
    342.             rt=send(sock,m_cSendBuff,strlen(m_cSendBuff),0);  
    343.             pt+=min(len-pt,3000);  
    344.             if(rt!=strlen(m_cSendBuff))  
    345.             {  
    346.                 return false;  
    347.             }  
    348.         }  
    349.         if(len!=0)  
    350.         {  
    351.             delete [] m_pcFileBuff;  
    352.         }  
    353.     }  
    354.   
    355.     return true;  
    356. }  
    357.   
    358. bool CSendMail::SendEnd(SOCKET &sock)  
    359. {  
    360.     sprintf_s(m_cSendBuff,"--INVT-- . ");  
    361.     send(sock,m_cSendBuff,strlen(m_cSendBuff),0);  
    362.   
    363.     sprintf_s(m_cSendBuff,"QUIT ");  
    364.     send(sock,m_cSendBuff,strlen(m_cSendBuff),0);  
    365.     closesocket(sock);  
    366.     WSACleanup();  
    367.     return true;  
    368. }  
    369.   
    370.   
    371. bool CSendMail::SendMail(sMailInfo &smailInfo)  
    372. {  
    373.     memcpy(&m_sMailInfo,&smailInfo,sizeof(smailInfo));  
    374.     if(m_sMailInfo.m_pcBody==NULL  
    375.         || m_sMailInfo.m_pcIPAddr==NULL  
    376.         || m_sMailInfo.m_pcIPName==NULL  
    377.         || m_sMailInfo.m_pcReceiver==NULL  
    378.         || m_sMailInfo.m_pcSender==NULL  
    379.         || m_sMailInfo.m_pcSenderName==NULL  
    380.         || m_sMailInfo.m_pcTitle==NULL  
    381.         || m_sMailInfo.m_pcUserName==NULL  
    382.         || m_sMailInfo.m_pcUserPassWord==NULL)  
    383.     {  
    384.         return false;  
    385.     }  
    386.     SOCKET sock;  
    387.     if(!CReateSocket(sock))//建立连接  
    388.     {  
    389.         return false;  
    390.     }  
    391.   
    392.     if(!Logon(sock))//登录邮箱  
    393.     {  
    394.         return false;  
    395.     }  
    396.   
    397.     if(!SendHead(sock))//发送邮件头  
    398.     {  
    399.         return false;  
    400.     }  
    401.   
    402.     if(!SendTextBody(sock))//发送邮件文本部分  
    403.     {  
    404.         return false;  
    405.     }  
    406.   
    407.     if(!SendFileBody(sock))//发送附件  
    408.     {  
    409.         return false;  
    410.     }  
    411.   
    412.     if(!SendEnd(sock))//结束邮件,并关闭sock  
    413.     {  
    414.         return false;  
    415.     }  
    416.   
    417.     return true;  
    418. }  
  • 相关阅读:
    绿盟UTS综合威胁探针管理员任意登录
    深信服EDR3.2.21任意代码执行
    linux反弹shell总结
    mysql在8.0版本下修改密码的命令
    Linux提权常用漏洞速查表
    windows提权常用系统漏洞与补丁编号速查对照表
    通达OA<=11.5版本SQL注入——附件上传
    通达OA<=11.5版本SQL注入——日程安排
    希尔伯特曲线python3实现
    深信服edr控制中心漏洞——验证码逻辑错误
  • 原文地址:https://www.cnblogs.com/lvdongjie/p/4148063.html
Copyright © 2020-2023  润新知