📄 hwsmtp.cpp
字号:
// HwSMTP.cpp: implementation of the CHwSMTP class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "HwSMTP.h"
#include "Base64.h"
#include <Afxmt.h>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
CPtrArray g_PtrAry_Threads;
::CCriticalSection m_CSFor__g_PtrAry_Threads;
class CEMailObject
{
public:
CEMailObject (
LPCTSTR lpszSmtpSrvHost,
LPCTSTR lpszUserName,
LPCTSTR lpszPasswd,
BOOL bMustAuth,
LPCTSTR lpszAddrFrom,
LPCTSTR lpszAddrTo,
LPCTSTR lpszSenderName,
LPCTSTR lpszReceiverName,
LPCTSTR lpszSubject,
LPCTSTR lpszBody,
LPCTSTR lpszCharSet,
CStringArray *pStrAryAttach,
CStringArray *pStrAryCC,
UINT nSmtpSrvPort
)
{
m_csSmtpSrvHost = GET_SAFE_STRING(lpszSmtpSrvHost);
m_csUserName = GET_SAFE_STRING(lpszUserName);
m_csPasswd = GET_SAFE_STRING(lpszPasswd);
m_bMustAuth = bMustAuth;
m_csAddrFrom = GET_SAFE_STRING(lpszAddrFrom);
m_csAddrTo = GET_SAFE_STRING(lpszAddrTo);
m_csSenderName = GET_SAFE_STRING(lpszSenderName);
m_csReceiverName = GET_SAFE_STRING(lpszReceiverName);
m_csSubject = GET_SAFE_STRING(lpszSubject);
m_csBody = GET_SAFE_STRING(lpszBody);
m_csCharSet = GET_SAFE_STRING(lpszCharSet);
if ( pStrAryAttach )
m_StrAryAttach.Append ( *pStrAryAttach );
if ( pStrAryCC )
m_StrAryCC.Append ( *pStrAryCC );
m_nSmtpSrvPort = nSmtpSrvPort;
m_hThread = NULL;
}
public:
CString m_csSmtpSrvHost;
CString m_csUserName;
CString m_csPasswd;
BOOL m_bMustAuth;
CString m_csAddrFrom;
CString m_csAddrTo;
CString m_csSenderName;
CString m_csReceiverName;
CString m_csSubject;
CString m_csBody;
CString m_csCharSet;
CStringArray m_StrAryAttach;
CStringArray m_StrAryCC;
UINT m_nSmtpSrvPort;
HANDLE m_hThread;
};
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CHwSMTP::CHwSMTP () :
m_bConnected ( FALSE ),
m_nSmtpSrvPort ( 25 ),
m_bMustAuth ( TRUE )
{
m_csMIMEContentType = _T( "multipart/mixed");
m_csPartBoundary = _T( "WC_MAIL_PaRt_BoUnDaRy_05151998" );
m_csNoMIMEText = _T( "This is a multi-part message in MIME format." );
// m_csCharSet = _T("\r\n\tcharset=\"iso-8859-1\"\r\n");
}
CHwSMTP::~CHwSMTP()
{
}
BOOL CHwSMTP::SendEmail (
LPCTSTR lpszSmtpSrvHost,
LPCTSTR lpszUserName,
LPCTSTR lpszPasswd,
BOOL bMustAuth,
LPCTSTR lpszAddrFrom,
LPCTSTR lpszAddrTo,
LPCTSTR lpszSenderName,
LPCTSTR lpszReceiverName,
LPCTSTR lpszSubject,
LPCTSTR lpszBody,
LPCTSTR lpszCharSet, // 字符集类型,例如:繁体中文这里应输入"big5",简体中文时输入"gb2312"
CStringArray *pStrAryAttach/*=NULL*/,
CStringArray *pStrAryCC/*=NULL*/,
UINT nSmtpSrvPort/*=25*/
)
{
TRACE ( _T("发送邮件:%s, %s, %s\n"), lpszAddrTo, lpszReceiverName, lpszBody );
m_StrAryAttach.RemoveAll();
m_StrAryCC.RemoveAll();
m_csSmtpSrvHost = GET_SAFE_STRING ( lpszSmtpSrvHost );
if ( m_csSmtpSrvHost.GetLength() <= 0 )
{
m_csLastError.Format ( _T("Parameter Error!") );
return FALSE;
}
m_csUserName = GET_SAFE_STRING ( lpszUserName );
m_csPasswd = GET_SAFE_STRING ( lpszPasswd );
m_bMustAuth = bMustAuth;
if ( m_bMustAuth && m_csUserName.GetLength() <= 0 )
{
m_csLastError.Format ( _T("Parameter Error!") );
return FALSE;
}
m_csAddrFrom = GET_SAFE_STRING ( lpszAddrFrom );
m_csAddrTo = GET_SAFE_STRING ( lpszAddrTo );
m_csSenderName = GET_SAFE_STRING ( lpszSenderName );
m_csReceiverName = GET_SAFE_STRING ( lpszReceiverName );
m_csSubject = GET_SAFE_STRING ( lpszSubject );
m_csBody = GET_SAFE_STRING ( lpszBody );
m_nSmtpSrvPort = nSmtpSrvPort;
if ( lpszCharSet && lstrlen(lpszCharSet) > 0 )
m_csCharSet.Format ( _T("\r\n\tcharset=\"%s\"\r\n"), lpszCharSet );
if (
m_csAddrFrom.GetLength() <= 0 || m_csAddrTo.GetLength() <= 0 ||
m_csSenderName.GetLength() <= 0 || m_csReceiverName.GetLength() <= 0 ||
m_csSubject.GetLength() <= 0 || m_csBody.GetLength() <= 0
)
{
m_csLastError.Format ( _T("Parameter Error!") );
return FALSE;
}
if ( pStrAryAttach )
{
m_StrAryAttach.Append ( *pStrAryAttach );
}
if ( m_StrAryAttach.GetSize() < 1 )
m_csMIMEContentType = _T( "text/plain");
if ( pStrAryCC )
{
m_StrAryCC.Append ( *pStrAryCC );
}
// 创建Socket
if ( !m_SendSock.Create () )
{
m_csLastError.Format ( _T("Create socket failed!") );
return FALSE;
}
// 连接到服务器
if ( !m_SendSock.Connect ( m_csSmtpSrvHost, m_nSmtpSrvPort ) )
{
m_csLastError.Format ( _T("Connect to [ %s ] failed"), m_csSmtpSrvHost );
TRACE ( _T("%d\n"), GetLastError() );
return FALSE;
}
if ( !GetResponse( _T("220") ) ) return FALSE;
m_bConnected = TRUE;
return SendEmail();
}
BOOL CHwSMTP::GetResponse ( LPCTSTR lpszVerifyCode, int *pnCode/*=NULL*/)
{
if ( !lpszVerifyCode || lstrlen(lpszVerifyCode) < 1 )
return FALSE;
char szRecvBuf[1024] = {0};
int nRet = 0;
char szStatusCode[4] = {0};
nRet = m_SendSock.Receive ( szRecvBuf, sizeof(szRecvBuf) );
TRACE ( _T("Received : %s\r\n"), szRecvBuf );
if ( nRet <= 0 )
{
m_csLastError.Format ( _T("Receive TCP data failed") );
return FALSE;
}
// TRACE ( _T("收到服务器回应:%s\n"), szRecvBuf );
memcpy ( szStatusCode, szRecvBuf, 3 );
if ( pnCode ) (*pnCode) = atoi ( szStatusCode );
if ( strcmp ( szStatusCode, CMultiByteString(lpszVerifyCode).GetBuffer() ) != 0 )
{
m_csLastError.Format ( _T("Received invalid response : %s"), GetCompatibleString(szRecvBuf,FALSE) );
return FALSE;
}
return TRUE;
}
// 利用socket发送数据,数据长度不能超过10M
BOOL CHwSMTP::Send(LPCTSTR lpszData, ... )
{
if ( !m_bConnected )
{
m_csLastError.Format ( _T("Didn't connect") );
return FALSE;
}
TCHAR *buf = NULL;
// 循环格式化字符串,如果缓冲不够则将缓冲加大然后重试以保证缓冲够用同时又不浪费
for ( int nBufCount = 1024; nBufCount<10*1024*1024; nBufCount += 1024 )
{
buf = new TCHAR[nBufCount];
if ( !buf )
{
::AfxThrowMemoryException ();
return FALSE;
}
memset ( buf, 0, nBufCount*sizeof(TCHAR) );
va_list va;
va_start (va, lpszData);
int nLen = _vsnprintf_hw ((TCHAR*)buf, nBufCount-sizeof(TCHAR), lpszData, va);
va_end(va);
if ( nLen <= (int)(nBufCount-sizeof(TCHAR)) )
break;
delete[] buf; buf = NULL;
}
if ( !buf )
{
m_csLastError.Format ( _T("Memory too small or data too big.") );
return FALSE;
}
CMultiByteString cbsData ( buf );
delete[] buf; buf = NULL;
TRACE ( _T("Send : %s\r\n"), cbsData.GetBuffer() );
if ( m_SendSock.Send ( cbsData.GetBuffer(), cbsData.GetLength() ) != cbsData.GetLength() )
{
m_csLastError.Format ( _T("Socket send data failed") );
return FALSE;
}
return TRUE;
}
BOOL CHwSMTP::SendEmail()
{
BOOL bRet = TRUE;
char szLocalHostName[64] = {0};
gethostname ( (char*)szLocalHostName, sizeof(szLocalHostName) );
// hello,握手
if ( !Send ( _T("HELO %s\r\n"), GetCompatibleString(szLocalHostName,FALSE) ) )
{
return FALSE;
}
if ( !GetResponse ( _T("250") ) )
{
return FALSE;
}
// 身份验证
if ( m_bMustAuth && !auth() )
{
return FALSE;
}
// 发送邮件头
if ( !SendHead() )
{
return FALSE;
}
// 发送邮件主题
if ( !SendSubject() )
{
return FALSE;
}
// 发送邮件正文
if ( !SendBody() )
{
return FALSE;
}
// 发送附件
if ( !SendAttach() )
{
return FALSE;
}
// 结束邮件正文
if ( !Send ( _T(".\r\n") ) ) return FALSE;
if ( !GetResponse ( _T("250") ) )
return FALSE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -