您的位置:首页 > 编程语言 > C语言/C++

一个C++ 发送邮件的类

2015-10-19 09:18 302 查看
/***********************************************************************
*发送邮件模块头文件
*可以发送文本和附件(支持多个附件一起发送)
*************************************************************************/
#pragma once
struct SMailInfo //邮件信息
{
//	char*   m_pcUserName;//用户登录邮箱的名称
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 CSendMailTool
{
public:
CSendMailTool(void);
~CSendMailTool(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(unsigned char* pBuff64, unsigned 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;
};

源文件

#include "StdAfx.h"
#include "SendMailTool.h"

/************************************************************************
* 发送邮件模块
*可以发送文本和附件(支持多个附件一起发送)
*Date:2011-12-01
************************************************************************/
#include "StdAfx.h"
#include "SendMailTool.h"
#include "winsock2.h"
#pragma comment(lib,"WSOCK32")
#pragma comment(lib, "ws2_32")

CSendMailTool::CSendMailTool(void)
{
m_pcFileBuff=NULL;
memset(m_cSendBuff,0,sizeof(m_cSendBuff));
memset(m_cReceiveBuff,0,sizeof(m_cReceiveBuff));
}

CSendMailTool::~CSendMailTool(void)
{
DeleteAllPath();
}

void CSendMailTool::Char2Base64(unsigned char* dest, unsigned char* src, int srclen)
{
int sign = 0;

const unsigned char EncodeIndex[] = {
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/'
};

for (int i = 0; i!= srclen; i++,src++,dest++)
{
switch(sign)
{
case 0:
*(dest) = EncodeIndex[*src >> 2];
break;
case 1:
*dest = EncodeIndex[((*(src-1) & 0x03) << 4) | (((*src) & 0xF0) >> 4)];
break;
case 2:
*dest = EncodeIndex[((*(src-1) &0x0F) << 2) | ((*(src) & 0xC0) >> 6)];
*(++dest) = EncodeIndex[(*(src) &0x3F)];
break;
}
(sign == 2)?(sign = 0):(sign++);
}
switch(sign)
{
case 0:
break;
case 1:
*(dest++) = EncodeIndex[((*(src-1) & 0x03) << 4) | (((*src) & 0xF0) >> 4)];
*(dest++) = '=';
*(dest++) = '=';
break;
case 2:
*(dest++) = EncodeIndex[((*(src-1) &0x0F) << 2) | ((*(src) & 0xC0) >> 6)];
*(dest++) = '=';
break;
default:
break;
}
}

void CSendMailTool::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 CSendMailTool::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 CSendMailTool::DeleteAllPath(void)
{
m_pcFilePathList.RemoveAll();
}

int CSendMailTool::GetFileData(char* FilePath)
{
m_pcFileBuff=NULL;
if(FilePath==NULL)
{
return 0;
}

CFile f;
int len;

USES_CONVERSION;
if(!f.Open(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;
}

/*
* 从完整文件路径中,取文件名
*
* 修正当filePath只有文件名时,fileName没取到
*/
void CSendMailTool::GetFileName(char* fileName,char* filePath)
{
if(filePath==NULL || fileName==NULL)
{
return;
}

char * pName =strrchr(filePath,'\\');
if(pName==NULL)//路径中只有文件名
pName=filePath;
else
pName++;

strcpy(fileName, pName);
}

bool CSendMailTool::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);//使用名称
if (hp == NULL)
{
DWORD dwErrCode = GetLastError();
return false;
}
servaddr.sin_addr.s_addr=*(int*)(*hp->h_addr_list);
}

int ret = connect(sock,(sockaddr*)&servaddr,sizeof(servaddr));//建立连接
if (ret == SOCKET_ERROR)
{
DWORD dwErr = GetLastError();
return false;
}

return true;
}

bool CSendMailTool::Logon(SOCKET &sock)
{
char local_host[MAX_PATH];

if ( gethostname(local_host, MAX_PATH) != 0 )
{
return false;
}
recv(sock,m_cReceiveBuff,1024,0);
memset(m_cSendBuff,0,sizeof(m_cSendBuff));
sprintf_s(m_cSendBuff,"HELO %s\r\n", local_host);

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((unsigned char*)m_cSendBuff,(unsigned char*)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((unsigned char*) m_cSendBuff,(unsigned char*) 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 CSendMailTool::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 CSendMailTool::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 CSendMailTool::SendFileBody(SOCKET &sock)
{
int i;
char* filePath;
int rt;
int len;
int pt=0;
char fileName[MAX_PATH];

for(i=0;i<m_pcFilePathList.GetCount();i++)
{
pt=0;
memset(fileName,0,MAX_PATH);
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( (unsigned char*) m_cSendBuff,(unsigned char*) &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 CSendMailTool::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 CSendMailTool::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;
}
使用
void TestSendMail()
{
CTime t = CTime::GetCurrentTime(); //获取系统日期

int d=t.GetDay(); //获得几号

int y=t.GetYear(); //获取年份

int m=t.GetMonth(); //获取当前月份

int h=t.GetHour(); //获取当前为几时

int mm=t.GetMinute(); //获取分钟

int nowtime=m*1000000+d*10000+h*100+mm;
char str3[50];
char str1[12]={0};
itoa(nowtime,str1,10);

char* str2="【警告】服务器出现清算错误_";
strcpy(str3,str2);
strcat(str3,str1);
char* str=(LPSTR)str3;

SMailInfo mailInfo;

//126 smtp
mailInfo.m_pcUserName = "1233333@163.com"; //"你的邮箱帐号";
mailInfo.m_pcUserPassWord = "ssssssssss"; // "密码";
mailInfo.m_pcSenderName = "交易服务器提示"; //发送邮件者的名称
mailInfo.m_pcSender = "super.tornado@163.com"; //发送者的邮箱地址

mailInfo.m_pcReceiver = "dddddddd@qq.com"; //接收者的邮箱地址
mailInfo.m_pcTitle = str; //邮箱标题
mailInfo.m_pcBody = "1234567979797979797979"; //邮件文本正文
mailInfo.m_pcIPAddr = ""; //服务器的IP可以留空
mailInfo.m_pcIPName = "smtp.163.com" ; //服务器的名称(IP与名称二选一,优先取名称)

CSendMail smtpMail;
smtpMail.AddFilePath("cDisp.log"); //附件1 可给出完整的附件路径
smtpMail.AddFilePath("TradeSrv.log"); //附件2
smtpMail.SendMail(mailInfo);
}

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;

// 初始化 MFC 并在失败时显示错误
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// TODO: 更改错误代码以符合您的需要
_tprintf(_T("错误: MFC 初始化失败\n"));
nRetCode = 1;
}
else
{
// TODO: 在此处为应用程序的行为编写代码。
}

TestSendMail();
return nRetCode;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: