一个C++ 发送邮件的类

/*********************************************************************** 
*发送邮件模块头文件 
*可以发送文本和附件(支持多个附件一起发送) 
*************************************************************************/  
#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;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值