?? smtp.cpp
字號:
// SMTP.cpp: implementation of the CSMTP class.
//
#include "stdafx.h"
#include "SMTP.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
CSMTP::response_code CSMTP::response_table[] =
{
{ 250, _T( "SMTP server error" ) },
{ 220, _T( "SMTP server not available" ) },
{ 354, _T( "SMTP server not ready for data" ) },
{ 221, _T( "SMTP server didn't terminate session" ) }
};
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CSMTP::CSMTP( LPCTSTR szSMTPServerName, UINT nPort )
{
ASSERT( szSMTPServerName != NULL );
AfxSocketInit();
m_sSMTPServerHostName = szSMTPServerName;
m_nPort = nPort;
m_bConnected = FALSE;
m_sError = _T( "OK" );
response_buf = NULL;
}
CSMTP::~CSMTP()
{
Disconnect();
}
CString CSMTP::GetServerHostName()
{
return m_sSMTPServerHostName;
}
// 定義存放主機名的緩沖區大小
#define HOSTNAMELENGTH 88
BOOL CSMTP::Connect()
{
CString sHello;
TCHAR local_host[HOSTNAMELENGTH];
// 如果已經建立了連接則返回
if( m_bConnected )
return TRUE;
response_buf = new TCHAR[RESPONSE_BUFFER_SIZE];
if(response_buf == NULL)
{
m_sError = _T("內存不夠用了");
return FALSE;
}
if(!m_wsSMTPServer.Create())
{
// 建立套接字失敗
m_sError = _T("無法創建套接字!");
delete response_buf;
response_buf = NULL;
return FALSE;
}
if(!m_wsSMTPServer.Connect(GetServerHostName(),GetPort()))
{
m_sError = _T("無法與服務器建立連接!");
m_wsSMTPServer.Close();
delete response_buf;
response_buf = NULL;
return FALSE;
}
if(!get_response(CONNECT_SUCCESS))
{
// 接收應答信息失敗
m_sError = _T("服務器沒有回答");
m_wsSMTPServer.Close();
delete response_buf;
response_buf = NULL;
return FALSE;
}
gethostname(local_host,HOSTNAMELENGTH);
// 以HELO命令開始發信
sHello.Format(_T("HELO %s\r\n"),local_host);
m_wsSMTPServer.Send((LPCTSTR)sHello,sHello.GetLength());
if(!get_response(GENERIC_SUCCESS))
{
// 獲得應答信息失敗
m_wsSMTPServer.Close();
delete response_buf;
response_buf = NULL;
return FALSE;
}
m_bConnected = TRUE;
return TRUE;
}
BOOL CSMTP::Disconnect()
{
BOOL bRet;
if(!m_bConnected)
return TRUE;
// 發送QUIT命令斷開連接
CString strQuit = _T( "QUIT\r\n" );
m_wsSMTPServer.Send((LPCTSTR)strQuit, strQuit.GetLength());
bRet = get_response(QUIT_SUCCESS);
// 關閉套接字
m_wsSMTPServer.Close();
// 釋放資源,并將連接標志置為FALSE
if( response_buf != NULL )
{
delete[] response_buf;
response_buf = NULL;
}
m_bConnected = FALSE;
return bRet;
}
UINT CSMTP::GetPort()
{
return m_nPort;
}
CString CSMTP::GetLastError()
{
return m_sError;
}
BOOL CSMTP::SendMessage(CMailMessage * msg)
{
if (msg == NULL)
{
// msg為空是沒有意義的
return FALSE;
}
// 如果還沒有建立連接
if(!m_bConnected)
{
m_sError = _T("喲,忘了先連服務器了");
return FALSE;
}
if(!FormatMailMessage(msg))
{
// 如果調整消息體的格式不成功
return FALSE;
}
if(!transmit_message(msg))
{
// 如果消息體發送不成功
return FALSE;
}
return TRUE;
}
BOOL CSMTP::FormatMailMessage( CMailMessage* msg )
{
if (msg == NULL)
{
// msg為空是沒有意義的
return FALSE;
}
if(!msg->GetNumRecipients())
{
m_sError = _T("No Recipients");
return FALSE;
}
// 在CMailMessage中封裝了“格式化”消息的功能
msg->FormatMessage();
return TRUE;
}
void CSMTP::SetServerProperties( LPCTSTR szSMTPServerName, UINT nPort)
{
if( szSMTPServerName == NULL )
return;
m_sSMTPServerHostName = szSMTPServerName;
m_nPort = nPort;
}
CString CSMTP::cook_body(CMailMessage * msg)
{
ASSERT(msg);
CString strTemp = msg->m_sBody;
CString strCook = _T("");
CString strBad = _T("\r\n.\r\n");
CString strGood = _T("\r\n..\r\n");
int nPos,nStart = 0,nBadLength = strBad.GetLength();
if (strTemp.Left(3) == _T(".\r\n"))
strTemp = _T(".") + strTemp;
while ((nPos = strTemp.Find(strBad)) > -1)
{
strCook = strTemp.Mid(nStart,nPos);
strCook += strGood;
strTemp = strCook + strTemp.Right(strTemp.GetLength() - (nPos + nBadLength));
}
return strTemp;
}
BOOL CSMTP::transmit_message(CMailMessage * msg)
{
CString strFrom,strTo,strTemp,strEmail;
if (msg == NULL)
return FALSE;
if(!m_bConnected)
{
// 若還未建立連接
m_sError = _T("請先建立連接!");
return FALSE;
}
// 發送MAIL命令
strFrom.Format(_T( "MAIL From: <%s>\r\n" ),(LPCTSTR)msg->m_sFrom);
m_wsSMTPServer.Send((LPCTSTR)strFrom,strFrom.GetLength());
if(!get_response(GENERIC_SUCCESS))
return FALSE;
// 發送RCPT命令
for(int i = 0;i < msg->GetNumRecipients();i++)
{
msg->GetRecipient(strEmail,strTemp,i);
strTo.Format(_T("RCPT TO: <%s>\r\n"),(LPCTSTR)strEmail);
m_wsSMTPServer.Send((LPCTSTR)strTo,strTo.GetLength());
get_response(GENERIC_SUCCESS);
}
// 處理抄送
for(i = 0;i < msg->GetNumRecipients(CMailMessage::CC);i++)
{
msg->GetRecipient(strEmail,strTemp,i,CMailMessage::CC);
strTo.Format(_T("RCPT TO: <%s>\r\n"),(LPCTSTR)strEmail);
m_wsSMTPServer.Send((LPCTSTR)strTo,strTo.GetLength());
get_response(GENERIC_SUCCESS);
}
// 處理暗送
for(i = 0;i < msg->GetNumRecipients(CMailMessage::BCC);i++)
{
msg->GetRecipient(strEmail,strTemp,i,CMailMessage::BCC);
strTo.Format(_T( "RCPT TO: <%s>\r\n"),(LPCTSTR)strEmail);
m_wsSMTPServer.Send((LPCTSTR)strTo,strTo.GetLength());
get_response(GENERIC_SUCCESS);
}
// 發送DATA命令
strTemp = _T("DATA\r\n");
m_wsSMTPServer.Send((LPCTSTR)strTemp,strTemp.GetLength());
if(!get_response(DATA_SUCCESS))
{
// 發送DATA命令失敗
return FALSE;
}
// 發送郵件頭
m_wsSMTPServer.Send((LPCTSTR)msg->m_sHeader,msg->m_sHeader.GetLength());
// 發送郵件正文
strTemp = cook_body(msg);
m_wsSMTPServer.Send((LPCTSTR)strTemp,strTemp.GetLength());
// 給郵件正文加上結束標志
strTemp = _T("\r\n.\r\n");
m_wsSMTPServer.Send((LPCTSTR)strTemp,strTemp.GetLength());
if(!get_response(GENERIC_SUCCESS) )
{
return FALSE;
}
return TRUE;
}
BOOL CSMTP::get_response(UINT response_expected)
{
ASSERT( response_expected >= GENERIC_SUCCESS );
ASSERT( response_expected < LAST_RESPONSE );
CString sResponse;
UINT response;
response_code* pResp;
if( m_wsSMTPServer.Receive( response_buf, RESPONSE_BUFFER_SIZE ) == SOCKET_ERROR )
{
m_sError = _T("套接字錯誤");
return FALSE;
}
sResponse = response_buf;
sscanf((LPCTSTR)sResponse.Left(3),_T("%d"),&response );
pResp = &response_table[response_expected];
if(response != pResp->nResponse)
{
m_sError.Format(_T("%d : %s"),response,(LPCTSTR)pResp->sMessage );
return FALSE;
}
return TRUE;
}
void CSMTP::Cancel()
{
// 取消阻塞的連接
m_wsSMTPServer.CancelBlockingCall();
// 關閉套接字
m_wsSMTPServer.Close();
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -