smtp协议 VC实现发送邮件

来源:互联网 发布:js array 方法大全 编辑:程序博客网 时间:2024/06/03 23:39
利用VC2005实现了邮件发送,源程序如下://-------------------------------------------------------SmtpSendEmail.h------------------------------------#pragma once#include <list> #include <string> #include <fstream> #include<WinSock2.h>#pragma comment(lib, "ws2_32.lib")using namespace std;#ifndef _SMTPSENDEMAIL_H#define _SMTPSENDEMAIL_H//发送线程DWORD WINAPI SendMailThread(LPVOID lpParam);class SmtpSendEmail {public: SmtpSendEmail(void); virtual ~SmtpSendEmail(void);public: void SetPost( int nPost );void SetHost( string strHost );void SetAccount( string strAccount );void SetPassword( string strPassword );void SetMailFrom( string strMailFrom );void SetSendTo( string strSendTo );void SetSubject( string strSubject );void SetDateTime( string strDateTime );bool AddDataFromString( string strData ); bool AddDataFromBuffer( char* szData, int iLen ); bool AddDataFromFile( string strFileName ); bool AddAttachedFile( string strFilePath, string strFileName );bool SandThread(); bool StarMailThread();private: int Base64EncodeLen( int nSrcLen ); bool Base64Encode( const BYTE* szSrcData, int nSrcLen, BYTE* szDestData, int* pnDestLen ); bool CheckResponse(int nResCode);bool ConnectServ();bool SendHelo();bool SendEhlo();bool AutoLogin();bool EmailFrom();bool EmailTo();bool DataServ();bool SendData();bool SendAttachedFile();bool QuitServ();private:     static const char   m_szBase64CodeTable[];     static const string MIMEMultipartMixedLogin;     static const string MIMETextPlainLogin;     static const string MyBoundary;     static const string CTCodeQP;     static const string CTCodeBase64;     static const string CTTextPlainCharCodeGB2312;     static const string CTAppOctetStreamName;     static const string CDAttachemntFileName;     struct SMTPSTRU     {         int    nPost;         string strHost;         string strAccount;         string strPassword;         string strMailFrom;         string strSendTo;         string strSubject;         string strDateTime;         string strData;     };     struct FILEINFOSTRU     {         string strPath;         string strFile;     }; SOCKET             m_hSocket;    SMTPSTRU           m_smtpPro;     list<FILEINFOSTRU> m_listFileInfo; };#endif//------------------------------------------------SmtpSendEmail.cpp------------------------------------------------------#include "StdAfx.h"#include "SmtpSendEmail.h"//发送线程DWORD WINAPI SendMailThread(LPVOID lpParam){((SmtpSendEmail*)lpParam)->SandThread();return 0;}const char SmtpSendEmail::m_szBase64CodeTable[]       = { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" }; const string SmtpSendEmail::MIMEMultipartMixedLogin   = "X-Mailer: Gddsky mailer\r\n MIME-Version: 1.0\r\nContent-type: multipart/mixed;boundary=\"===_000_Gddsky_000_===\"\r\n\r\n";const string SmtpSendEmail::MIMETextPlainLogin        = "X-Mailer: Gddsky mailer\r\nMIME-Version: 1.0\r\nContent-type: text/plain;charset=\"GB2312\"\r\n Content-Transfer-Encoding: base64\r\n\r\n"; const string SmtpSendEmail::MyBoundary                = "\r\n--===_000_Gddsky_000_===\r\n"; const string SmtpSendEmail::CTCodeQP                  = "Content-Transfer-Encoding: quoted-printable\r\n\r\n"; const string SmtpSendEmail::CTCodeBase64              = "Content-Transfer-Encoding: base64\r\n\r\n"; const string SmtpSendEmail::CTTextPlainCharCodeGB2312 = "Content-Type: text/plain;charset=\"GB2312\"\r\n"; const string SmtpSendEmail::CTAppOctetStreamName      = "Content-Type: application/octet-stream;name="; const string SmtpSendEmail::CDAttachemntFileName      = "Content-Disposition: attachment;filename="; SmtpSendEmail::SmtpSendEmail(void) { WSADATA wsaData = {0};WORD wVersionRequested = MAKEWORD( 2, 2 );WSAStartup( wVersionRequested, &wsaData );     m_smtpPro.nPost = 25;m_hSocket = 0;} SmtpSendEmail::~SmtpSendEmail(void) {      m_listFileInfo.clear(); //关闭SOCKclosesocket(m_hSocket);m_hSocket = 0;WSACleanup();} int SmtpSendEmail::Base64EncodeLen( int nSrcLen ) { int nRet = nSrcLen * 4 / 3 + nSrcLen % 3;     int nCRLFs = ( nRet / 76 + 1 ) * 2;     int nOnLastLine = nRet % 76;     nRet += nCRLFs;     if( nOnLastLine && nOnLastLine % 4 )     {         nRet += 4 - ( nOnLastLine % 4 );     }     return nRet; } bool SmtpSendEmail::Base64Encode( const BYTE* szSrcData, int nSrcLen, BYTE* szDestData, int* pnDestLen ) { if( !( szSrcData && nSrcLen && szDestData && pnDestLen && *pnDestLen ) ) {    return false; } if( *pnDestLen < Base64EncodeLen( nSrcLen ) ) {    return false; } int nWritten = 0 ; int nLen1 = ( nSrcLen / 3 ) * 4; int nLen2 = nLen1 / 76; int nLen3 = 19; for( int i = 0; i <= nLen2; i++ ) {    if( i == nLen2 )    {     nLen3 = ( nLen1 % 76 ) / 4;    }    for( int j = 0; j < nLen3; j++ )    {     DWORD dwCurr = 0;     for( int n = 0; n < 3; n++ )     {      dwCurr |= *szSrcData++;      dwCurr <<= 8;     }     for( int k = 0; k < 4; k++ )     {      BYTE b = ( BYTE )( dwCurr >> 26 );                 *szDestData++ = m_szBase64CodeTable[ b ];                 dwCurr <<= 6;     }    }    nWritten += nLen3 * 4;    *szDestData++ = '\r';    *szDestData++ = '\n';    nWritten+= 2; } if( nWritten ) {    szDestData-= 2;    nWritten -= 2; } nLen2 = ( nSrcLen % 3 ) ? ( nSrcLen % 3 ) + 1 : 0; if( nLen2 ) {    DWORD dwCurr = 0;    for( int n = 0; n < 3; n++ )    {     if( n < ( nSrcLen % 3 ) )     {      dwCurr |= *szSrcData++;     }     dwCurr <<= 8;    }    for( int k = 0; k < nLen2; k++ )    {     BYTE b = ( BYTE ) ( dwCurr >> 26 );             *szDestData++ = m_szBase64CodeTable[ b ];             dwCurr <<= 6;    }    nWritten += nLen2;    nLen3 = nLen2 ? 4 - nLen2 : 0;    for( int j = 0; j < nLen3; j++ )    {     *szDestData++ = '=';    }    nWritten += nLen3; } *pnDestLen = nWritten;return true; }void SmtpSendEmail::SetPost( int nPost ){ m_smtpPro.nPost = nPost; }void SmtpSendEmail::SetHost( string strHost ){m_smtpPro.strHost = strHost; }void SmtpSendEmail::SetAccount( string strAccount ){m_smtpPro.strAccount = strAccount; }void SmtpSendEmail::SetPassword( string strPassword ){ m_smtpPro.strPassword = strPassword;}void SmtpSendEmail::SetMailFrom( string strMailFrom ){ m_smtpPro.strMailFrom = strMailFrom; }void SmtpSendEmail::SetSendTo( string strSendTo ){ m_smtpPro.strSendTo = strSendTo;    }void SmtpSendEmail::SetSubject( string strSubject ){ m_smtpPro.strSubject = strSubject;   }void SmtpSendEmail::SetDateTime( string strDateTime ){ m_smtpPro.strDateTime = strDateTime;} bool SmtpSendEmail::AddDataFromString( std::string strData ) { m_smtpPro.strData.append( strData.c_str() ); return true; } bool SmtpSendEmail::AddDataFromBuffer( char* szData, int iLen ) { if( NULL != szData && iLen > 0) {    m_smtpPro.strData.append( szData, iLen );    return true; } return false; } bool SmtpSendEmail::AddDataFromFile( string strFileName ) { ifstream InputFile; InputFile.open( strFileName.c_str(), ios_base::binary | ios_base::in ); if( InputFile.fail() ) {    return false; } InputFile.seekg( 0, ios_base::end ); int iLen = InputFile.tellg(); InputFile.seekg( 0, ios_base::beg ); char* pszFileData = new char[iLen + 1]; memset(pszFileData, 0, iLen + 1);InputFile.read( pszFileData, iLen ); m_smtpPro.strData.append( pszFileData ); delete pszFileData;return true; } bool SmtpSendEmail::AddAttachedFile(string strFilePath, string strFileName) { FILEINFOSTRU fileInfo; fileInfo.strPath = strFilePath; fileInfo.strFile = strFileName; m_listFileInfo.push_back(fileInfo); return true;}bool SmtpSendEmail::StarMailThread(){DWORD threadID;HANDLE threadHandle = CreateThread(0, 0, SendMailThread, this, 0, &threadID);return true;}// 发送邮件 bool SmtpSendEmail::SandThread() {//创建SOCK,连接服务器if (!ConnectServ()){   return false;}    //HELO CMDif(!SendHelo()){   return false;}//EHLO CMDif (SendEhlo()){   if (!AutoLogin())   {    return false;   }}//MAIL FORM CMDif (!EmailFrom()){   return false;}//RCPT TO CMDif (!EmailTo()){   return false;}//DATA CMDif (!DataServ()){   return false;}// 邮件内容if (m_listFileInfo.size() > 0){   if (!SendAttachedFile())   {    return false;   }}else{   if (!SendData())   {    return false;   }}// 发送结束 if (!QuitServ()){   return false;}//关闭SOCKclosesocket(m_hSocket);m_hSocket = 0;    return true; }bool SmtpSendEmail::ConnectServ(){//创建SOCKm_hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//超时struct timeval timeoutRecv = {0};timeoutRecv.tv_sec = 30000;setsockopt(m_hSocket, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeoutRecv, sizeof(timeoutRecv));//连接LPHOSTENT pHost = gethostbyname(m_smtpPro.strHost.c_str());struct sockaddr_in servAddr;servAddr.sin_family = AF_INET;servAddr.sin_addr.s_addr = *(ULONG *)pHost->h_addr_list[0];servAddr.sin_port = htons(25);if (connect(m_hSocket, (const struct sockaddr *)&servAddr, sizeof(struct sockaddr_in)) == SOCKET_ERROR){   closesocket(m_hSocket);   m_hSocket = 0;   return false;}return CheckResponse(220);}bool SmtpSendEmail::CheckResponse(int nResCode){char szRecvBuf[1024] = {0};char szTemp[20] = {0};_itoa_s(nResCode, szTemp, 20, 10);//接收回复int nRecvLen = recv(m_hSocket, szRecvBuf, 1024, 0);if (nRecvLen <= 0){   closesocket(m_hSocket);   m_hSocket = 0;   return false;}if (nRecvLen >= (int)strlen(szTemp)){   if (strstr(szRecvBuf, szTemp) != NULL)   {    return true;   }}return false;}bool SmtpSendEmail::SendHelo(){string strSendBuf;strSendBuf.append( "HELO " );strSendBuf.append(m_smtpPro.strHost.c_str());strSendBuf.append("\r\n");//发送int nSendLen = send(m_hSocket, strSendBuf.c_str(), (int)strSendBuf.size(), 0);if (nSendLen != (int)strSendBuf.size()){   closesocket(m_hSocket);   m_hSocket = 0;   return false;}//回复return CheckResponse(250);}bool SmtpSendEmail::SendEhlo(){string strSendBuf;strSendBuf.append( "EHLO 126.com \r\n" );//strSendBuf.append(m_smtpPro.Host.c_str());//strSendBuf.append("\r\n");//发送int nSendLen = send(m_hSocket, strSendBuf.c_str(), (int)strSendBuf.size(), 0);if (nSendLen != (int)strSendBuf.size()){   closesocket(m_hSocket);   m_hSocket = 0;   return false;}//回复return CheckResponse(250);}bool SmtpSendEmail::AutoLogin(){int nTemp = 1024;char szBaseBuf[1024] = {0};string strSendBuf;strSendBuf.append( "AUTH LOGIN\r\n" ); //发送int nSendLen = send(m_hSocket, strSendBuf.c_str(), (int)strSendBuf.size(), 0);if (nSendLen != (int)strSendBuf.size()){   closesocket(m_hSocket);   m_hSocket = 0;   return false;}//回复if (!CheckResponse(334)){   return false;}//帐户strSendBuf.clear();Base64Encode( (const BYTE*)m_smtpPro.strAccount.c_str(), (int)m_smtpPro.strAccount.size(), (BYTE*)szBaseBuf, &nTemp ); strSendBuf.append( szBaseBuf ); //发送nSendLen = send(m_hSocket, strSendBuf.c_str(), (int)strSendBuf.size(), 0);if (nSendLen != (int)strSendBuf.size()){   closesocket(m_hSocket);   m_hSocket = 0;   return false;}//回复if (!CheckResponse(334)){   return false;}//密码strSendBuf.clear();nTemp = 1024; memset(szBaseBuf, 0, 1024 ); Base64Encode( (const BYTE*)m_smtpPro.strPassword.c_str(), (int)m_smtpPro.strPassword.size(), (BYTE*)szBaseBuf, &nTemp ); strSendBuf.append( szBaseBuf ); //发送nSendLen = send(m_hSocket, strSendBuf.c_str(), (int)strSendBuf.size(), 0);if (nSendLen != (int)strSendBuf.size()){   closesocket(m_hSocket);   m_hSocket = 0;   return false;}//回复return CheckResponse(235);}bool SmtpSendEmail::EmailFrom(){string strSendBuf;strSendBuf.append( "MAIL FROM: <" ); strSendBuf.append( m_smtpPro.strMailFrom.c_str() ); strSendBuf.append( ">\r\n" ); //发送int nSendLen = send(m_hSocket, strSendBuf.c_str(), (int)strSendBuf.size(), 0);if (nSendLen != (int)strSendBuf.size()){   closesocket(m_hSocket);   m_hSocket = 0;   return false;}//回复return CheckResponse(250);}bool SmtpSendEmail::EmailTo(){string strSendBuf;strSendBuf.append( "RCPT TO: <" ); strSendBuf.append( m_smtpPro.strSendTo.c_str() ); strSendBuf.append( ">\r\n" ); //发送int nSendLen = send(m_hSocket, strSendBuf.c_str(), (int)strSendBuf.size(), 0);if (nSendLen != (int)strSendBuf.size()){   closesocket(m_hSocket);   m_hSocket = 0;   return false;}//回复return CheckResponse(250);}bool SmtpSendEmail::DataServ(){string strSendBuf;strSendBuf.append( "DATA\r\n" ); //发送int nSendLen = send(m_hSocket, strSendBuf.c_str(), (int)strSendBuf.size(), 0);if (nSendLen != (int)strSendBuf.size()){   closesocket(m_hSocket);   m_hSocket = 0;   return false;}//回复return CheckResponse(354);}bool SmtpSendEmail::SendData(){string strSendBuf;strSendBuf.append( "From: <" ); strSendBuf.append( m_smtpPro.strMailFrom.c_str() ); strSendBuf.append( ">\r\n" );strSendBuf.append( "To: <" ); strSendBuf.append( m_smtpPro.strSendTo.c_str() ); strSendBuf.append( ">\r\n" );strSendBuf.append( "Date: " ); strSendBuf.append( m_smtpPro.strDateTime.c_str() ); strSendBuf.append( "\r\n" );strSendBuf.append( "Subject: " ); strSendBuf.append( m_smtpPro.strSubject.c_str() ); strSendBuf.append( "\r\n" );strSendBuf.append( MIMETextPlainLogin.c_str() );//内容strSendBuf.append(m_smtpPro.strData.c_str());//结束符strSendBuf.append("\r\n.\r\n");//发送int nSendLen = send(m_hSocket, strSendBuf.c_str(), (int)strSendBuf.size(), 0);if (nSendLen != (int)strSendBuf.size()){   closesocket(m_hSocket);   m_hSocket = 0;   return false;}//回复return CheckResponse(250);}bool SmtpSendEmail::SendAttachedFile(){string strSendBuf;strSendBuf.append( "From: <" ); strSendBuf.append( m_smtpPro.strMailFrom.c_str() ); strSendBuf.append( ">\r\n" );strSendBuf.append( "To: <" ); strSendBuf.append( m_smtpPro.strSendTo.c_str() ); strSendBuf.append( ">\r\n" );strSendBuf.append( "Date: " ); strSendBuf.append( m_smtpPro.strDateTime.c_str() ); strSendBuf.append( "\r\n" );strSendBuf.append( "Subject: " ); strSendBuf.append( m_smtpPro.strSubject.c_str() ); strSendBuf.append( "\r\n" );strSendBuf.append( MIMEMultipartMixedLogin.c_str() );strSendBuf.append( MyBoundary.c_str() ); strSendBuf.append( CTTextPlainCharCodeGB2312.c_str() ); strSendBuf.append( CTCodeBase64.c_str() ); //内容加密int nSize = Base64EncodeLen( (int)m_smtpPro.strData.size() ); BYTE *pszDataBuf = new BYTE[nSize+1];memset(pszDataBuf, 0, nSize+1);Base64Encode( (const BYTE*)m_smtpPro.strData.c_str(), (int)m_smtpPro.strData.size(), (BYTE*)pszDataBuf, &nSize ); strSendBuf.append((char*)pszDataBuf);delete pszDataBuf;//发送int nSendLen = send(m_hSocket, strSendBuf.c_str(), (int)strSendBuf.size(), 0);if (nSendLen != (int)strSendBuf.size()){   closesocket(m_hSocket);   m_hSocket = 0;   return false;}//附件for( list<FILEINFOSTRU>::iterator it = m_listFileInfo.begin(); it != m_listFileInfo.end(); it++ ) {    string strFile = ( *it ).strPath + ( *it ).strFile;    string strFileData;    // 读文件    ifstream InputFile;    InputFile.open( strFile.c_str(), ios_base::binary | ios_base::in );    if( InputFile.fail() )    {     continue;    }    InputFile.seekg( 0, ios_base::end );    int iLen = InputFile.tellg();    InputFile.seekg( 0, ios_base::beg );   strFileData.resize( iLen );    InputFile.read( (char*)strFileData.c_str(), iLen );   // 加入一个附件头    strSendBuf.clear();    strSendBuf.append( MyBoundary.c_str() );    strSendBuf.append( CTAppOctetStreamName.c_str() );    strSendBuf.append( ( *it ).strFile.c_str() );    strSendBuf.append( "\r\n" );    strSendBuf.append( CDAttachemntFileName.c_str() );    strSendBuf.append( ( *it ).strFile.c_str() );    strSendBuf.append( "\r\n" );    strSendBuf.append( CTCodeBase64.c_str() );    //内容加密   nSize = Base64EncodeLen( (int)strFileData.size() );    pszDataBuf = new BYTE[nSize+1];   memset(pszDataBuf, 0, nSize+1);   Base64Encode( (const BYTE*)strFileData.c_str(), (int)strFileData.size(), (BYTE*)pszDataBuf, &nSize );    strSendBuf.append((char*)pszDataBuf);   delete pszDataBuf;   //发送   nSendLen = send(m_hSocket, strSendBuf.c_str(), (int)strSendBuf.size(), 0);   if (nSendLen != (int)strSendBuf.size())   {    closesocket(m_hSocket);    m_hSocket = 0;    return false;   }} //结束符strSendBuf.clear();strSendBuf.append("\r\n.\r\n");//发送nSendLen = send(m_hSocket, strSendBuf.c_str(), (int)strSendBuf.size(), 0);if (nSendLen != (int)strSendBuf.size()){   closesocket(m_hSocket);   m_hSocket = 0;   return false;}//回复return CheckResponse(250);}bool SmtpSendEmail::QuitServ(){string strSendBuf = "QUIT\r\n"; int nSendLen = send(m_hSocket, strSendBuf.c_str(), (int)strSendBuf.size(), 0);if (nSendLen != (int)strSendBuf.size()){   closesocket(m_hSocket);   m_hSocket = 0;   return false;}//回复return CheckResponse(221);} 测试代码:m_smtp.SetHost("smtp.126.com");m_smtp.SetPost(25);m_smtp.SetAccount("yefeng654321");m_smtp.SetPassword("密码");m_smtp.SetMailFrom("yefeng654321@126.com");m_smtp.SetSendTo("yefeng654321@126.com");m_smtp.SetSubject("测试");m_smtp.SetDateTime("2008-12-29");m_smtp.AddDataFromBuffer("123456789", 9);m_smtp.AddAttachedFile("c:\\","1.txt");m_smtp.StarMailThread();

原创粉丝点击