首页 > 编程 > C++ > 正文

C++实现发送邮件和附件功能

2020-05-23 13:26:38
字体:
来源:转载
供稿:网友

本文实例为大家分享了C++实现发送邮件和附件的具体代码,供大家参考,具体内容如下

头文件

/**************************发送邮件模块头文件 *可以发送文本和附件(支持多个附件一起发送) **************************/ #pragma once struct sMailInfo //邮件信息 {  char* m_pcUserName;//用户登录邮箱的名称  char* m_pcUserPassWord;//用户登录邮箱的密码  char* m_pcSenderName;//用户发送时显示的名称  char* m_pcSender;//发送者的邮箱地址  char* m_pcReceiver;//接收者的邮箱地址  char* m_pcTitle;//邮箱标题  char* m_pcBody;//邮件文本正文  char* m_pcIPAddr;//服务器的IP  char* m_pcIPName;//服务器的名称(IP与名称二选一,优先取名称)  sMailInfo(){memset(this,0,sizeof(sMailInfo));} }; class CSendMail { public:  CSendMail(void);  ~CSendMail(void);  public:  bool SendMail(sMailInfo &smailInfo);//发送邮件,需要在发送的时候初始化邮件信息  void AddFilePath(char * pcFilePath);//添加附件的决定路径到附件列表中  void DeleteFilePath(char* pcFilePath);//删除附件路径,如果有的话  void DeleteAllPath(void);//删除全部附件的路径  protected:  void GetFileName(char* fileName,char* filePath);//从附件的路径中获取文件名称  void Char2Base64(char* pBuff64,char* pSrcBuff,int iLen);//把char类型转换成Base64类型  bool CReateSocket(SOCKET &sock);//建立socket连接  bool Logon(SOCKET &sock);//登录邮箱,主要进行发邮件前的准备工作  int GetFileData(char* FilePath);//由文件路径获取附件内容   bool SendHead(SOCKET &sock);//发送邮件头  bool SendTextBody(SOCKET &sock);//发送邮件文本正文  bool SendFileBody(SOCKET &sock);//发送邮件附件  bool SendEnd(SOCKET &sock);//发送邮件结尾 protected:  CList<char*,char*> m_pcFilePathList;//记录附件路径   char m_cSendBuff[4096];//发送缓冲区  char m_cReceiveBuff[1024];  char* m_pcFileBuff;//指向附件内容  sMailInfo m_sMailInfo; }; 

模块实现文件

/***************************** 发送邮件模块 *可以发送文本和附件(支持多个附件一起发送) *Date:2011-12-01 ******************************/ #include "StdAfx.h" #include "SendMail.h" #include "winsock2.h" #pragma comment(lib,"WSOCK32")  CSendMail::CSendMail(void) {  m_pcFileBuff=NULL;  memset(m_cSendBuff,0,sizeof(m_cSendBuff));  memset(m_cReceiveBuff,0,sizeof(m_cReceiveBuff)); }   CSendMail::~CSendMail(void) {  DeleteAllPath(); }   void CSendMail::Char2Base64(char* pBuff64,char* pSrcBuff,int iLen) {  //1 1 1 1 1 1 1 1  // 分配给pBuff64 ↑ 分配给pBuff64+1  //   point所在的位置  static char Base64Encode[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";//base64所映射的字符表  int point;//每一个源字符拆分的位置,可取2,4,6;初始为2  point=2;  int i;  int iIndex;//base64字符的索引  char n=0;//上一个源字符的残留值  for(i=0;i<iLen;i++)  {   if(point==2)   {    iIndex=((*pSrcBuff)>>point)&0x3f;//取得pSrcBuff的高point位   }   else if (point==4)   {    iIndex=((*pSrcBuff)>>point)&0xf;//取得pSrcBuff的高point位   }   else if(point==6)   {    iIndex=((*pSrcBuff)>>point)&0x3;//取得pSrcBuff的高point位   }   iIndex+=n;//与pSrcBuff-1的低point结合组成Base64的索引   *pBuff64++=Base64Encode[iIndex];//由索引表得到pBuff64   n=((*pSrcBuff)<<(6-point));//计算源字符中的残留值   n=n&0x3f;//确保n的最高两位为0   point+=2;//源字符的拆分位置上升2   if(point==8)//如果拆分位置为8说明pSrcBuff有6位残留,可以组成一个完整的Base64字符,所以直接再组合一次   {    iIndex=(*pSrcBuff)&0x3f;//提取低6位,这就是索引了    *pBuff64++=Base64Encode[iIndex];//    n=0;//残留值为0    point=2;//拆分位置设为2   }   pSrcBuff++;   }  if(n!=0)  {   *pBuff64++=Base64Encode[n];  }  if(iLen%3==2)//如果源字符串长度不是3的倍数要用'='补全  {   *pBuff64='=';  }  else if(iLen%3==1)  {   *pBuff64++='=';   *pBuff64='=';  } }  void CSendMail::AddFilePath(char * pcFilePath)//添加附件路径 {  if(pcFilePath==NULL)  {   return;  }  int i;  char* temp;  for(i=0;i<m_pcFilePathList.GetCount();i++)  {   temp=m_pcFilePathList.GetAt(m_pcFilePathList.FindIndex(i));   if(strcmp(pcFilePath,temp)==0)//如果已经存在就不用再添加了   {    return;   }  }  m_pcFilePathList.AddTail(pcFilePath); }  void CSendMail::DeleteFilePath(char* pcFilePath)//删除附件路径 {  int i;  char* temp;  for(i=0;i<m_pcFilePathList.GetCount();i++)  {   temp=m_pcFilePathList.GetAt(m_pcFilePathList.FindIndex(i));   if(strcmp(temp,pcFilePath)==0)//找到并删除它,如果没找到就算了   {    m_pcFilePathList.RemoveAt(m_pcFilePathList.FindIndex(i));    delete[] temp;    return;   }  } }   void CSendMail::DeleteAllPath(void) {  m_pcFilePathList.RemoveAll(); }  int CSendMail::GetFileData(char* FilePath) {  m_pcFileBuff=NULL;  if(FilePath==NULL)  {   return 0;  }  CFile f;  int len;      USES_CONVERSION;  if(!f.Open(A2W(FilePath),CFile::modeRead|CFile::modeNoTruncate|CFile::typeBinary))  {   return 0;  }  len=(int)f.GetLength();  m_pcFileBuff=new char[len+1];  memset(m_pcFileBuff,0,len+1);  f.Read(m_pcFileBuff,len);   f.Close();  return len; }  void CSendMail::GetFileName(char* fileName,char* filePath) {  if(filePath==NULL || fileName==NULL)  {   return;  }  int i;  for(i=0;i<(int)strlen(filePath);i++)  {   if(filePath[strlen(filePath)-1-i]=='//')   {    memcpy(fileName,&filePath[strlen(filePath)-i],i);    return;   }  } }  bool CSendMail::CReateSocket(SOCKET &sock) {  WORD wVersionRequested;  WSADATA wsaData;  int err;  wVersionRequested = MAKEWORD( 2, 2 );  err = WSAStartup( wVersionRequested, &wsaData );  if ( err != 0 )  {   return false;  }  if ( LOBYTE( wsaData.wVersion ) != 2 ||   HIBYTE( wsaData.wVersion ) != 2 )  {   WSACleanup( );   return false;  }  sock = socket(AF_INET,SOCK_STREAM,IPPROTO_IP);  if (sock == INVALID_SOCKET)  {   return false;  }   sockaddr_in servaddr;  memset(&servaddr,0,sizeof(sockaddr_in));  servaddr.sin_family = AF_INET;  servaddr.sin_port = htons(25);//发邮件一般都是25端口  if(m_sMailInfo.m_pcIPName=="")  {   servaddr.sin_addr.s_addr = inet_addr(m_sMailInfo.m_pcIPAddr);//直接使用IP地址  }  else  {   struct hostent *hp=gethostbyname(m_sMailInfo.m_pcIPName);//使用名称   servaddr.sin_addr.s_addr=*(int*)(*hp->h_addr_list);  }    int ret = connect(sock,(sockaddr*)&servaddr,sizeof(servaddr));//建立连接  if (ret == SOCKET_ERROR)  {   return false;  }   return true; }   bool CSendMail::Logon(SOCKET &sock) {  recv(sock,m_cReceiveBuff,1024,0);   memset(m_cSendBuff,0,sizeof(m_cSendBuff));  sprintf_s(m_cSendBuff,"HELO []/r/n");  send(sock,m_cSendBuff,strlen(m_cSendBuff),0);//开始会话  recv(sock,m_cReceiveBuff,1024,0);  if(m_cReceiveBuff[0]!='2' || m_cReceiveBuff[1]!='5' || m_cReceiveBuff[2]!='0')  {   return false;  }   memset(m_cSendBuff,0,sizeof(m_cSendBuff));  sprintf_s(m_cSendBuff,"AUTH LOGIN/r/n");  send(sock,m_cSendBuff,strlen(m_cSendBuff),0);//请求登录  recv(sock,m_cReceiveBuff,1024,0);  if(m_cReceiveBuff[0]!='3' || m_cReceiveBuff[1]!='3' || m_cReceiveBuff[2]!='4')  {   return false;  }   memset(m_cSendBuff,0,sizeof(m_cSendBuff));  Char2Base64(m_cSendBuff,m_sMailInfo.m_pcUserName,strlen(m_sMailInfo.m_pcUserName));  m_cSendBuff[strlen(m_cSendBuff)]='/r';  m_cSendBuff[strlen(m_cSendBuff)]='/n';  send(sock,m_cSendBuff,strlen(m_cSendBuff),0);//发送用户名  recv(sock,m_cReceiveBuff,1024,0);  if(m_cReceiveBuff[0]!='3' || m_cReceiveBuff[1]!='3' || m_cReceiveBuff[2]!='4')  {   return false;  }   memset(m_cSendBuff,0,sizeof(m_cSendBuff));  Char2Base64(m_cSendBuff,m_sMailInfo.m_pcUserPassWord,strlen(m_sMailInfo.m_pcUserPassWord));  m_cSendBuff[strlen(m_cSendBuff)]='/r';  m_cSendBuff[strlen(m_cSendBuff)]='/n';  send(sock,m_cSendBuff,strlen(m_cSendBuff),0);//发送用户密码  recv(sock,m_cReceiveBuff,1024,0);  if(m_cReceiveBuff[0]!='2' || m_cReceiveBuff[1]!='3' || m_cReceiveBuff[2]!='5')  {   return false;  }  return true;//登录成功 }   bool CSendMail::SendHead(SOCKET &sock) {  int rt;  memset(m_cSendBuff,0,sizeof(m_cSendBuff));  sprintf_s(m_cSendBuff,"MAIL FROM:<%s>/r/n",m_sMailInfo.m_pcSender);  rt=send(sock,m_cSendBuff,strlen(m_cSendBuff),0);    if(rt!=strlen(m_cSendBuff))  {   return false;  }  recv(sock,m_cReceiveBuff,1024,0);   memset(m_cSendBuff,0,sizeof(m_cSendBuff));  sprintf_s(m_cSendBuff,"RCPT TO:<%s>/r/n",m_sMailInfo.m_pcReceiver);  rt=send(sock,m_cSendBuff,strlen(m_cSendBuff),0);  if(rt!=strlen(m_cSendBuff))  {   return false;  }  recv(sock,m_cReceiveBuff,1024,0);   memset(m_cSendBuff,0,sizeof(m_cSendBuff));  memcpy(m_cSendBuff,"DATA/r/n",strlen("DATA/r/n"));  rt=send(sock,m_cSendBuff,strlen(m_cSendBuff),0);  if(rt!=strlen(m_cSendBuff))  {   return false;  }  recv(sock,m_cReceiveBuff,1024,0);   memset(m_cSendBuff,0,sizeof(m_cSendBuff));  sprintf_s(m_cSendBuff,"From:/"%s/"<%s>/r/n",m_sMailInfo.m_pcSenderName,m_sMailInfo.m_pcSender);  sprintf_s(&m_cSendBuff[strlen(m_cSendBuff)],150,"To:/"INVT.COM.CN/"<%s>/r/n",m_sMailInfo.m_pcReceiver);  sprintf_s(&m_cSendBuff[strlen(m_cSendBuff)],150,"Subject:%s/r/nMime-Version: 1.0/r/nContent-Type: multipart/mixed; boundary=/"INVT/"/r/n/r/n",m_sMailInfo.m_pcTitle);  rt=send(sock,m_cSendBuff,strlen(m_cSendBuff),0);  if(rt!=strlen(m_cSendBuff))  {   return false;  }   return true; }  bool CSendMail::SendTextBody(SOCKET &sock) {  int rt;  memset(m_cSendBuff,0,sizeof(m_cSendBuff));  sprintf_s(m_cSendBuff,"--INVT/r/nContent-Type: text/plain;/r/n charset=/"gb2312/"/r/n/r/n%s/r/n/r/n",m_sMailInfo.m_pcBody);  rt=send(sock,m_cSendBuff,strlen(m_cSendBuff),0);  if(rt!=strlen(m_cSendBuff))  {   return false;  }  else  {   return true;  } }  bool CSendMail::SendFileBody(SOCKET &sock) {  int i;  char* filePath;  int rt;  int len;  int pt=0;  char fileName[128];  for(i=0;i<m_pcFilePathList.GetCount();i++)  {   pt=0;   memset(fileName,0,128);   filePath=m_pcFilePathList.GetAt(m_pcFilePathList.FindIndex(i));   len=GetFileData(filePath);   GetFileName(fileName,filePath);    sprintf_s(m_cSendBuff,"--INVT/r/nContent-Type: application/octet-stream;/r/n name=/"%s/"/r/nContent-Transfer-Encoding: base64/r/nContent-Disposition: attachment;/r/n filename=/"%s/"/r/n/r/n",fileName,fileName);   send(sock,m_cSendBuff,strlen(m_cSendBuff),0);   while (pt<len)   {    memset(m_cSendBuff,0,sizeof(m_cSendBuff));    Char2Base64(m_cSendBuff,&m_pcFileBuff[pt],min(len-pt,3000));    m_cSendBuff[strlen(m_cSendBuff)]='/r';    m_cSendBuff[strlen(m_cSendBuff)]='/n';    rt=send(sock,m_cSendBuff,strlen(m_cSendBuff),0);    pt+=min(len-pt,3000);    if(rt!=strlen(m_cSendBuff))    {     return false;    }   }   if(len!=0)   {    delete [] m_pcFileBuff;   }  }   return true; }  bool CSendMail::SendEnd(SOCKET &sock) {  sprintf_s(m_cSendBuff,"--INVT--/r/n./r/n");  send(sock,m_cSendBuff,strlen(m_cSendBuff),0);   sprintf_s(m_cSendBuff,"QUIT/r/n");  send(sock,m_cSendBuff,strlen(m_cSendBuff),0);  closesocket(sock);  WSACleanup();  return true; }   bool CSendMail::SendMail(sMailInfo &smailInfo) {  memcpy(&m_sMailInfo,&smailInfo,sizeof(smailInfo));  if(m_sMailInfo.m_pcBody==NULL   || m_sMailInfo.m_pcIPAddr==NULL   || m_sMailInfo.m_pcIPName==NULL   || m_sMailInfo.m_pcReceiver==NULL   || m_sMailInfo.m_pcSender==NULL   || m_sMailInfo.m_pcSenderName==NULL   || m_sMailInfo.m_pcTitle==NULL   || m_sMailInfo.m_pcUserName==NULL   || m_sMailInfo.m_pcUserPassWord==NULL)  {   return false;  }  SOCKET sock;  if(!CReateSocket(sock))//建立连接  {   return false;  }   if(!Logon(sock))//登录邮箱  {   return false;  }   if(!SendHead(sock))//发送邮件头  {   return false;  }   if(!SendTextBody(sock))//发送邮件文本部分  {   return false;  }   if(!SendFileBody(sock))//发送附件  {   return false;  }   if(!SendEnd(sock))//结束邮件,并关闭sock  {   return false;  }   return true; } 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持VEVB武林网。


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表