博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
简单邮件系统程序
阅读量:4047 次
发布时间:2019-05-25

本文共 15292 字,大约阅读时间需要 50 分钟。

#include "stdafx.h"
#include "SmtpSendEmail.h"

//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 CSmtpSendEmail 
{
public: 
CSmtpSendEmail(void); 
virtual ~CSmtpSendEmail(void);
public: 
void SetPort( int nPost );
void SetHost( string strHost );
void SetAccount( string strAccount );
void SetPassword( string strPassword );
void SetMailFrom( string strMailFrom );
void SetSendTo( string strSendTo );
void SetSendTo( const std::vector<std::string>& vectSendTo);
void SetSubject( string strSubject );
void SetDateTime( string strDateTime );
void SetMailContent( const std::string& strData );
bool AddDataFromString( const std::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; 
std::vector<std::string> vectSendTo; 
string strSubject; 
string strDateTime; 
string strData; 
}; 
struct FILEINFOSTRU 
string strPath; 
string strFile; 
}; 
SOCKET             m_hSocket;
SMTPSTRU           m_smtpPro; 
list<FILEINFOSTRU> m_listFileInfo; 
};
#endif

//cpp文件

//发送线程
DWORD WINAPI SendMailThread(LPVOID lpParam)
{
((CSmtpSendEmail*)lpParam)->SandThread();
return 0;
}
const char CSmtpSendEmail::m_szBase64CodeTable[]       = { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" }; 
const string CSmtpSendEmail::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 CSmtpSendEmail::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 CSmtpSendEmail::MyBoundary                = "\r\n--===_000_Gddsky_000_===\r\n"; 
const string CSmtpSendEmail::CTCodeQP                  = "Content-Transfer-Encoding: quoted-printable\r\n\r\n"; 
const string CSmtpSendEmail::CTCodeBase64              = "Content-Transfer-Encoding: base64\r\n\r\n"; 
const string CSmtpSendEmail::CTTextPlainCharCodeGB2312 = "Content-Type: text/plain;charset=\"GB2312\"\r\n"; 
const string CSmtpSendEmail::CTAppOctetStreamName      = "Content-Type: application/octet-stream;name="; 
const string CSmtpSendEmail::CDAttachemntFileName      = "Content-Disposition: attachment;filename="; 
CSmtpSendEmail::CSmtpSendEmail(void) 
WSADATA wsaData = {0};
WORD wVersionRequested = MAKEWORD( 2, 2 );
WSAStartup( wVersionRequested, &wsaData );
m_smtpPro.nPost = 25;
m_hSocket = 0;
CSmtpSendEmail::~CSmtpSendEmail(void) 
m_listFileInfo.clear(); 
//关闭SOCK
closesocket(m_hSocket);
m_hSocket = 0;
WSACleanup();
int CSmtpSendEmail::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 CSmtpSendEmail::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 CSmtpSendEmail::SetPort( int nPost )
m_smtpPro.nPost = nPost; 
}
void CSmtpSendEmail::SetHost( string strHost )
{
m_smtpPro.strHost = strHost; 
}
void CSmtpSendEmail::SetAccount( string strAccount )
{
m_smtpPro.strAccount = strAccount; 
}
void CSmtpSendEmail::SetPassword( string strPassword )
m_smtpPro.strPassword = strPassword;
}
void CSmtpSendEmail::SetMailFrom( string strMailFrom )
m_smtpPro.strMailFrom = strMailFrom; 
}
void CSmtpSendEmail::SetSendTo( string strSendTo )
m_smtpPro.vectSendTo.clear();
m_smtpPro.vectSendTo.push_back(strSendTo);
}
void CSmtpSendEmail::SetSendTo( const std::vector<std::string>& vectSendTo)
m_smtpPro.vectSendTo = vectSendTo;    
}
void CSmtpSendEmail::SetSubject( string strSubject )
m_smtpPro.strSubject = strSubject;   
}
void CSmtpSendEmail::SetDateTime( string strDateTime )
m_smtpPro.strDateTime = strDateTime;
void CSmtpSendEmail::SetMailContent( const std::string& strData )
m_smtpPro.strData = strData.c_str(); 
return;
bool CSmtpSendEmail::AddDataFromString( const std::string& strData ) 
m_smtpPro.strData.append( strData.c_str() ); 
return true; 
bool CSmtpSendEmail::AddDataFromBuffer( char* szData, int iLen ) 
if( NULL != szData && iLen > 0) 
m_smtpPro.strData.append( szData, iLen ); 
return true; 
return false; 
bool CSmtpSendEmail::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 = (int)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 CSmtpSendEmail::AddAttachedFile(string strFilePath, string strFileName) 
FILEINFOSTRU fileInfo; 
fileInfo.strPath = strFilePath; 
fileInfo.strFile = strFileName; 
m_listFileInfo.push_back(fileInfo); 
return true;
}
bool CSmtpSendEmail::StarMailThread()
{
DWORD threadID;
HANDLE threadHandle = CreateThread(0, 0, SendMailThread, this, 0, &threadID);
return true;
}
// 发送邮件 
bool CSmtpSendEmail::SandThread() 
{
//创建SOCK,连接服务器
if (!ConnectServ())
{
return false;
}
//HELO CMD
if(!SendHelo())
{
return false;
}
//MAIL FORM CMD
if (!EmailFrom())
{
return false;
}
//RCPT TO CMD
if (!EmailTo())
{
return false;
}
//DATA CMD
if (!DataServ())
{
return false;
}
// 邮件内容
if (!SendData())
{
return false;
}
// 发送结束 
if (!QuitServ())
{
return false;
}
//关闭SOCK
closesocket(m_hSocket);
m_hSocket = 0;
return true; 
}
bool CSmtpSendEmail::ConnectServ()
{
LPHOSTENT pHost = gethostbyname(m_smtpPro.strHost.c_str());
if (pHost == NULL)
{
return false;
}
//创建SOCK
m_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));
//连接
struct sockaddr_in servAddr;
memset(&servAddr, 0, sizeof(sockaddr_in));
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = *(ULONG *)pHost->h_addr_list[0];
//servAddr.sin_addr = *((struct in_addr *)pHost->h_addr);//
servAddr.sin_port = htons(25);
if (connect(m_hSocket, (const struct sockaddr *)&servAddr, sizeof(struct sockaddr_in)) == SOCKET_ERROR)
{
int iResult = WSAGetLastError();
closesocket(m_hSocket);
m_hSocket = 0;
return false;
}
return CheckResponse(220);
}
bool CSmtpSendEmail::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);
printf(szRecvBuf );
printf("\r\n" );
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 CSmtpSendEmail::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);
printf(strSendBuf.c_str() );
printf("\r\n" );
if (nSendLen != (int)strSendBuf.size())
{
closesocket(m_hSocket);
m_hSocket = 0;
return false;
}
//回复
return CheckResponse(250);
}
bool CSmtpSendEmail::SendEhlo()
{
string strSendBuf;
strSendBuf.append( "EHLO " );
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 CSmtpSendEmail::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);
printf(strSendBuf.c_str() );
printf("\r\n" );
if (nSendLen != (int)strSendBuf.size())
{
closesocket(m_hSocket);
m_hSocket = 0;
return false;
}
//回复
return CheckResponse(250);
}
bool CSmtpSendEmail::EmailTo()
{
std::vector<std::string>::iterator iterVect = m_smtpPro.vectSendTo.begin();
for (; iterVect != m_smtpPro.vectSendTo.end(); ++iterVect)
{
string strSendBuf;
strSendBuf.append( "RCPT TO: <" ); 
strSendBuf.append( iterVect->c_str() ); 
strSendBuf.append( ">\r\n" ); 
//发送
int nSendLen = send(m_hSocket, strSendBuf.c_str(), (int)strSendBuf.size(), 0);
printf(strSendBuf.c_str() );
printf("\r\n" );
if (nSendLen != (int)strSendBuf.size())
{
closesocket(m_hSocket);
m_hSocket = 0;
return false;
}
//回复
bool bResult = CheckResponse(250);
if (!bResult)
{
return false;
}
}
return true;
}
bool CSmtpSendEmail::DataServ()
{
string strSendBuf;
strSendBuf.append( "DATA\r\n" ); 
//发送
int nSendLen = send(m_hSocket, strSendBuf.c_str(), (int)strSendBuf.size(), 0);
printf(strSendBuf.c_str() );
if (nSendLen != (int)strSendBuf.size())
{
closesocket(m_hSocket);
m_hSocket = 0;
return false;
}
//回复
return CheckResponse(354);
}
bool CSmtpSendEmail::SendData()
{
string strSendBuf;
strSendBuf.append( "From: <" ); 
strSendBuf.append( m_smtpPro.strMailFrom.c_str() ); 
strSendBuf.append( ">\r\n" );
strSendBuf.append( "TO: " ); 
std::vector<std::string>::iterator iterVect = m_smtpPro.vectSendTo.begin();
for (; iterVect != m_smtpPro.vectSendTo.end(); ++iterVect)
{
strSendBuf.append( iterVect->c_str() ); 
strSendBuf.append( ";" ); 
}
strSendBuf.append( "\r\n" ); 
strSendBuf.append( "Subject: " ); 
strSendBuf.append( m_smtpPro.strSubject.c_str() ); 
strSendBuf.append( "\r\n" );
//有个空行
strSendBuf.append( "\r\n" );
//内容
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 CSmtpSendEmail::SendAttachedFile()
{
string strSendBuf;
strSendBuf.append( "From: <" ); 
strSendBuf.append( m_smtpPro.strMailFrom.c_str() ); 
strSendBuf.append( ">\r\n" );
std::vector<std::string>::iterator iterVect = m_smtpPro.vectSendTo.begin();
for (; iterVect != m_smtpPro.vectSendTo.end(); ++iterVect)
{
strSendBuf.append( "TO: <" ); 
strSendBuf.append( iterVect->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 = (int)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 CSmtpSendEmail::QuitServ()
{
string strSendBuf = "QUIT\r\n"; 
int nSendLen = send(m_hSocket, strSendBuf.c_str(), (int)strSendBuf.size(), 0);
printf(strSendBuf.c_str() );
printf("\r\n");
if (nSendLen != (int)strSendBuf.size())
{
closesocket(m_hSocket);
m_hSocket = 0;
return false;
}
//回复
return CheckResponse(221);
}

转载地址:http://zpfci.baihongyu.com/

你可能感兴趣的文章
[互联网关注]李开复教大学生回答如何学好编程
查看>>
[关注大学生]李开复给中国计算机系大学生的7点建议
查看>>
[茶余饭后]10大毕业生必听得歌曲
查看>>
gdb调试命令的三种调试方式和简单命令介绍
查看>>
C++程序员的几种境界
查看>>
VC++ MFC SQL ADO数据库访问技术使用的基本步骤及方法
查看>>
VUE-Vue.js之$refs,父组件访问、修改子组件中 的数据
查看>>
Vue-子组件改变父级组件的信息
查看>>
Python自动化之pytest常用插件
查看>>
Python自动化之pytest框架使用详解
查看>>
【正则表达式】以个人的理解帮助大家认识正则表达式
查看>>
性能调优之iostat命令详解
查看>>
性能调优之iftop命令详解
查看>>
非关系型数据库(nosql)介绍
查看>>
移动端自动化测试-Windows-Android-Appium环境搭建
查看>>
Xpath使用方法
查看>>
移动端自动化测试-Mac-IOS-Appium环境搭建
查看>>
Selenium之前世今生
查看>>
Selenium-WebDriverApi接口详解
查看>>
Selenium-ActionChains Api接口详解
查看>>