C++實(shí)現(xiàn)發(fā)送郵件和附件功能
本文實(shí)例為大家分享了C++實(shí)現(xiàn)發(fā)送郵件和附件的具體代碼,供大家參考,具體內(nèi)容如下
頭文件
/*************************
*發(fā)送郵件模塊頭文件
*可以發(fā)送文本和附件(支持多個(gè)附件一起發(fā)送)
**************************/
#pragma once
struct sMailInfo //郵件信息
{
char* m_pcUserName;//用戶登錄郵箱的名稱
char* m_pcUserPassWord;//用戶登錄郵箱的密碼
char* m_pcSenderName;//用戶發(fā)送時(shí)顯示的名稱
char* m_pcSender;//發(fā)送者的郵箱地址
char* m_pcReceiver;//接收者的郵箱地址
char* m_pcTitle;//郵箱標(biāo)題
char* m_pcBody;//郵件文本正文
char* m_pcIPAddr;//服務(wù)器的IP
char* m_pcIPName;//服務(wù)器的名稱(IP與名稱二選一,優(yōu)先取名稱)
sMailInfo(){memset(this,0,sizeof(sMailInfo));}
};
class CSendMail
{
public:
CSendMail(void);
~CSendMail(void);
public:
bool SendMail(sMailInfo &smailInfo);//發(fā)送郵件,需要在發(fā)送的時(shí)候初始化郵件信息
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類型轉(zhuǎn)換成Base64類型
bool CReateSocket(SOCKET &sock);//建立socket連接
bool Logon(SOCKET &sock);//登錄郵箱,主要進(jìn)行發(fā)郵件前的準(zhǔn)備工作
int GetFileData(char* FilePath);//由文件路徑獲取附件內(nèi)容
bool SendHead(SOCKET &sock);//發(fā)送郵件頭
bool SendTextBody(SOCKET &sock);//發(fā)送郵件文本正文
bool SendFileBody(SOCKET &sock);//發(fā)送郵件附件
bool SendEnd(SOCKET &sock);//發(fā)送郵件結(jié)尾
protected:
CList<char*,char*> m_pcFilePathList;//記錄附件路徑
char m_cSendBuff[4096];//發(fā)送緩沖區(qū)
char m_cReceiveBuff[1024];
char* m_pcFileBuff;//指向附件內(nèi)容
sMailInfo m_sMailInfo;
};
模塊實(shí)現(xiàn)文件
/****************************
* 發(fā)送郵件模塊
*可以發(fā)送文本和附件(支持多個(gè)附件一起發(fā)送)
*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;//每一個(gè)源字符拆分的位置,可取2,4,6;初始為2
point=2;
int i;
int iIndex;//base64字符的索引
char n=0;//上一個(gè)源字符的殘留值
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結(jié)合組成Base64的索引
*pBuff64++=Base64Encode[iIndex];//由索引表得到pBuff64
n=((*pSrcBuff)<<(6-point));//計(jì)算源字符中的殘留值
n=n&0x3f;//確保n的最高兩位為0
point+=2;//源字符的拆分位置上升2
if(point==8)//如果拆分位置為8說明pSrcBuff有6位殘留,可以組成一個(gè)完整的Base64字符,所以直接再組合一次
{
iIndex=(*pSrcBuff)&0x3f;//提取低6位,這就是索引了
*pBuff64++=Base64Encode[iIndex];//
n=0;//殘留值為0
point=2;//拆分位置設(shè)為2
}
pSrcBuff++;
}
if(n!=0)
{
*pBuff64++=Base64Encode[n];
}
if(iLen%3==2)//如果源字符串長度不是3的倍數(shù)要用'='補(bǔ)全
{
*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)//如果已經(jīng)存在就不用再添加了
{
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);//發(fā)郵件一般都是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);//開始會(huì)話
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);//請(qǐng)求登錄
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);//發(fā)送用戶名
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);//發(fā)送用戶密碼
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))//發(fā)送郵件頭
{
return false;
}
if(!SendTextBody(sock))//發(fā)送郵件文本部分
{
return false;
}
if(!SendFileBody(sock))//發(fā)送附件
{
return false;
}
if(!SendEnd(sock))//結(jié)束郵件,并關(guān)閉sock
{
return false;
}
return true;
}
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C++實(shí)現(xiàn)歌手比賽評(píng)分系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)歌手比賽評(píng)分系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03
C++控制臺(tái)實(shí)現(xiàn)簡單注冊(cè)登錄
這篇文章主要為大家詳細(xì)介紹了C++控制臺(tái)實(shí)現(xiàn)簡單注冊(cè)登錄,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-12-12
C語言數(shù)據(jù)結(jié)構(gòu)之學(xué)生信息管理系統(tǒng)課程設(shè)計(jì)
這篇文章主要為大家詳細(xì)介紹了C語言數(shù)據(jù)結(jié)構(gòu)之學(xué)生信息管理系統(tǒng)課程設(shè)計(jì),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-11-11
概述C++中的 public protected private friend關(guān)鍵字的用法
這篇文章簡要概述了C++中的 public protected private friend關(guān)鍵字的用法,非常不錯(cuò),具有參考借鑒價(jià)值,感興趣的朋友一起學(xué)習(xí)吧2016-08-08
C++基于CreateToolhelp32Snapshot獲取系統(tǒng)進(jìn)程實(shí)例
這篇文章主要介紹了C++基于CreateToolhelp32Snapshot獲取系統(tǒng)進(jìn)程實(shí)例,是Windows應(yīng)用程序設(shè)計(jì)中非常實(shí)用的技巧,需要的朋友可以參考下2014-10-10
C語言實(shí)現(xiàn)電腦關(guān)機(jī)程序
這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)電腦關(guān)機(jī)程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-02-02

