⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hwsmtp.cpp

📁 邮件终端发送程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// 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 + -