本文實例為大家分享了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武林網。
新聞熱點
疑難解答