📄 hwsmtp.cpp
字号:
// 退出发送
if ( HANDLE_IS_VALID(m_SendSock.m_hSocket) )
Send ( _T("QUIT\r\n") );
m_bConnected = FALSE;
return bRet;
}
BOOL CHwSMTP::auth()
{
int nResponseCode = 0;
if ( !Send ( _T("auth login\r\n") ) ) return FALSE;
if ( !GetResponse ( _T("334"), &nResponseCode ) ) return FALSE;
if ( nResponseCode != 334 ) // 不需要验证用户名和密码
return TRUE;
CBase64 Base64Encode;
CMultiByteString cbsUserName ( m_csUserName ), cbsPasswd ( m_csPasswd );
CString csBase64_UserName = GetCompatibleString ( Base64Encode.Encode ( cbsUserName.GetBuffer(), cbsUserName.GetLength() ).GetBuffer(0), FALSE );
CString csBase64_Passwd = GetCompatibleString ( Base64Encode.Encode ( cbsPasswd.GetBuffer(), cbsPasswd.GetLength() ).GetBuffer(0), FALSE );
if ( !Send ( _T("%s\r\n"), csBase64_UserName ) ) return FALSE;
if ( !GetResponse ( _T("334") ) )
{
m_csLastError.Format ( _T("Authentication UserName failed") );
return FALSE;
}
if ( !Send ( _T("%s\r\n"), csBase64_Passwd ) ) return FALSE;
if ( !GetResponse ( _T("235") ) )
{
m_csLastError.Format ( _T("Authentication Password failed") );
return FALSE;
}
return TRUE;
}
BOOL CHwSMTP::SendHead()
{
if ( !Send ( _T("MAIL From: <%s>\r\n"), m_csAddrFrom ) ) return FALSE;
if ( !GetResponse ( _T("250") ) ) return FALSE;
if ( !Send ( _T("RCPT TO: <%s>\r\n"), m_csAddrTo ) ) return FALSE;
if ( !GetResponse ( _T("250") ) ) return FALSE;
for ( int i=0; i<m_StrAryCC.GetSize(); i++ )
{
if ( !Send ( _T("RCPT TO: <%s>\r\n"), m_StrAryCC.GetAt(i) ) ) return FALSE;
if ( !GetResponse ( _T("250") ) ) return FALSE;
}
if ( !Send ( _T("DATA\r\n") ) ) return FALSE;
if ( !GetResponse ( _T("354") ) ) return FALSE;
return TRUE;
}
BOOL CHwSMTP::SendSubject()
{
CString csSubject;
csSubject += _T("Date: ");
COleDateTime tNow = COleDateTime::GetCurrentTime();
if ( tNow > 1 )
{
csSubject += GetCompatibleString(FormatDateTime (tNow, "%a, %d %b %y %H:%M:%S %Z").GetBuffer(0),FALSE);
}
csSubject += _T("\r\n");
csSubject += FormatString ( _T("From: %s\r\nTo: %s\r\n"), m_csSenderName, m_csReceiverName );
csSubject += FormatString ( _T("Subject: %s\r\n"), m_csSubject );
csSubject += FormatString ( _T("X-Mailer: chrys\r\nMIME-Version: 1.0\r\nContent-Type: %s; %s boundary=%s\r\n\r\n") ,
m_csMIMEContentType, m_csCharSet, m_csPartBoundary );
return Send ( csSubject );
}
BOOL CHwSMTP::SendBody()
{
CString csBody, csTemp;
if ( m_StrAryAttach.GetSize() > 0 )
{
csTemp.Format ( _T("%s\r\n\r\n"), m_csNoMIMEText );
csBody += csTemp;
csTemp.Format ( _T("--%s\r\n"), m_csPartBoundary );
csBody += csTemp;
csTemp.Format ( _T("Content-Type: text/plain\r\n%sContent-Transfer-Encoding: 7Bit\r\n\r\n"),
m_csCharSet );
csBody += csTemp;
}
csTemp.Format ( _T("%s\r\n"), m_csBody );
csBody += csTemp;
if ( m_StrAryAttach.GetSize() > 0 )
{
csTemp.Format ( _T("--%s\r\n"), m_csPartBoundary );
csBody += csTemp;
}
return Send ( csBody );
}
BOOL CHwSMTP::SendAttach()
{
int nCountAttach = (int)m_StrAryAttach.GetSize();
if ( nCountAttach < 1 ) return TRUE;
for ( int i=0; i<nCountAttach; i++ )
{
if ( !SendOnAttach ( m_StrAryAttach.GetAt(i) ) )
return FALSE;
}
return TRUE;
}
BOOL CHwSMTP::SendOnAttach(LPCTSTR lpszFileName)
{
ASSERT ( lpszFileName );
CString csAttach, csTemp;
csTemp = lpszFileName;
CString csShortFileName = csTemp.GetBuffer(0) + csTemp.ReverseFind ( '\\' );
csShortFileName.TrimLeft ( _T("\\") );
csTemp.Format ( _T("Content-Type: application/octet-stream; file=%s\r\n"), csShortFileName );
csAttach += csTemp;
csTemp.Format ( _T("Content-Transfer-Encoding: base64\r\n") );
csAttach += csTemp;
csTemp.Format ( _T("Content-Disposition: attachment; filename=%s\r\n\r\n"), csShortFileName );
csAttach += csTemp;
DWORD dwFileSize = hwGetFileAttr(lpszFileName);
if ( dwFileSize > 5*1024*1024 )
{
m_csLastError.Format ( _T("File [%s] too big. File size is : %s"), lpszFileName, FormatBytes(dwFileSize) );
return FALSE;
}
char *pBuf = new char[dwFileSize+1];
if ( !pBuf )
{
::AfxThrowMemoryException ();
return FALSE;
}
CFile file;
try
{
if ( !file.Open ( lpszFileName, CFile::modeRead ) )
{
m_csLastError.Format ( _T("Open file [%s] failed"), lpszFileName );
return FALSE;
}
UINT nFileLen = file.Read ( pBuf, dwFileSize );
CBase64 Base64Encode;
csTemp = Base64Encode.Encode ( pBuf, nFileLen );
csAttach += csTemp;
csAttach += _T("\r\n\r\n");
}
catch ( CFileException e )
{
e.Delete();
m_csLastError.Format ( _T("Read file [%s] failed"), lpszFileName );
delete[] pBuf;
return FALSE;
}
csTemp.Format ( _T("--%s\r\n"), m_csPartBoundary );
csAttach += csTemp;
delete[] pBuf;
return Send ( csAttach );
}
CString CHwSMTP::GetLastErrorText()
{
return m_csLastError;
}
DWORD WINAPI ThreadProc_SendEmail( LPVOID lpParameter )
{
CEMailObject *pEMailObject = (CEMailObject*)lpParameter;
ASSERT ( pEMailObject );
CHwSMTP HwSMTP;
BOOL bRet = HwSMTP.SendEmail (
pEMailObject->m_csSmtpSrvHost,
pEMailObject->m_csUserName,
pEMailObject->m_csPasswd,
pEMailObject->m_bMustAuth,
pEMailObject->m_csAddrFrom,
pEMailObject->m_csAddrTo,
pEMailObject->m_csSenderName,
pEMailObject->m_csReceiverName,
pEMailObject->m_csSubject,
pEMailObject->m_csBody,
pEMailObject->m_csCharSet,
&pEMailObject->m_StrAryAttach,
&pEMailObject->m_StrAryCC,
pEMailObject->m_nSmtpSrvPort
);
if ( !bRet)
{
#ifdef _DEBUG
CString csError = HwSMTP.GetLastErrorText ();
csError = FormatString ( _T("Send a email to [%s] failed."), pEMailObject->m_csSmtpSrvHost );
AfxMessageBox ( csError );
#endif
}
m_CSFor__g_PtrAry_Threads.Lock ();
int nFindPos = FindFromArray ( g_PtrAry_Threads, pEMailObject->m_hThread );
if ( nFindPos >= 0 )
g_PtrAry_Threads.RemoveAt ( nFindPos );
m_CSFor__g_PtrAry_Threads.Unlock ();
delete pEMailObject;
return bRet;
}
//
// 用 SMTP 服务发送电子邮件,如果设置参数 bViaThreadSend=TRUE,那在程序结束时应该在 ExitInstance() 中调用 EndOfSMTP() 函数
//
BOOL SendEmail (
BOOL bViaThreadSend,
LPCTSTR lpszSmtpSrvHost,
LPCTSTR lpszUserName,
LPCTSTR lpszPasswd,
BOOL bMustAuth,
LPCTSTR lpszAddrFrom,
LPCTSTR lpszAddrTo,
LPCTSTR lpszSenderName,
LPCTSTR lpszReceiverName,
LPCTSTR lpszSubject,
LPCTSTR lpszBody,
LPCTSTR lpszCharSet/*=NULL*/,
CStringArray *pStrAryAttach/*=NULL*/,
CStringArray *pStrAryCC/*=NULL*/,
UINT nSmtpSrvPort/*=25*/
)
{
if ( !lpszSmtpSrvHost || lstrlen(lpszSmtpSrvHost) < 1 ||
!lpszSubject || lstrlen(lpszSubject) < 1 ||
!lpszBody || lstrlen(lpszBody) < 1 )
{
AfxMessageBox ( _T("Parameter error !") );
return FALSE;
}
CEMailObject *pEMailObject = new CEMailObject (
lpszSmtpSrvHost,
lpszUserName,
lpszPasswd,
bMustAuth,
lpszAddrFrom,
lpszAddrTo,
lpszSenderName,
lpszReceiverName,
lpszSubject,
lpszBody,
lpszCharSet,
pStrAryAttach,
pStrAryCC,
nSmtpSrvPort
);
if ( !pEMailObject ) return FALSE;
BOOL bRet = FALSE;
if ( bViaThreadSend )
{
DWORD dwThreadId = 0;
pEMailObject->m_hThread = ::CreateThread ( NULL, 0, ::ThreadProc_SendEmail, pEMailObject, CREATE_SUSPENDED, &dwThreadId );
bRet = HANDLE_IS_VALID(pEMailObject->m_hThread);
m_CSFor__g_PtrAry_Threads.Lock();
g_PtrAry_Threads.Add ( pEMailObject->m_hThread );
m_CSFor__g_PtrAry_Threads.Unlock();
ResumeThread ( pEMailObject->m_hThread );
}
else
{
bRet = (BOOL)ThreadProc_SendEmail ( pEMailObject );
}
return bRet;
}
void EndOfSMTP ()
{
// 等待所有线程执行完毕
for ( int i=0; i<g_PtrAry_Threads.GetSize(); i++ )
{
HANDLE hThread = (HANDLE)g_PtrAry_Threads.GetAt(i);
if ( HANDLE_IS_VALID(hThread) )
{
WaitForThreadEnd ( &hThread, 30*1000 );
}
}
g_PtrAry_Threads.RemoveAll ();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -