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

📄 smtp.cpp

📁 根据SMTP邮件传输协议,编写的简单的发送邮件的测试程序!
💻 CPP
字号:
#include "Smtp.h"
#include "MailMessage.h"
#include <assert.h>



Smtp::response_code Smtp::response_table[] =
{
	{ 250, "SMTP server error" },						// GENERIC_SUCCESS
	{ 220, "SMTP server not available" },				// CONNECT_SUCCESS
	{ 354, "SMTP server not ready for data" },			// DATA_SUCCESS
	{ 334, "SMTP server username failure"},				// USERNAME_SUCCESS
	{ 235, "SMTP server Login failure"},				// LOGIN_SUCCESS
	{ 221, "SMTP server didn't terminate session" }  	// QUIT_SUCCESS
};



Smtp::Smtp(string szSMTPServerName, uint nPort /* = SMTP_PORT */)
:m_bConnected(false)
,m_sSMTPServerHostName(szSMTPServerName)
,m_nPort(nPort)
{



}


Smtp::~Smtp()
{

	
}

void Smtp::SetServerProperties( string sServerHostName, uint nPort /* = SMTP_PORT  */)
{

	assert( !sServerHostName.empty());
	// Needs to be safe in non-debug too
	if( sServerHostName.empty())
		return;
	m_sSMTPServerHostName = sServerHostName;
	m_nPort = nPort;

}


string Smtp::GetLastError()
{

	return m_szError;

}



string Smtp::GetMailerName()
{

		return m_sMailerName;


}

uint Smtp::GetPort()
{

	return m_nPort;


}
	

bool Smtp::Disconnect()
{
	bool ret;
	if( !m_bConnected )
		return true;
	
	string sQuit =  "QUIT\r\n" ;
	m_wsSMTPServer.Send( (char*) sQuit.c_str(), sQuit.length() );
	
	
	ret = get_response( QUIT_SUCCESS );
	m_wsSMTPServer.Close();
	
	m_bConnected = FALSE;
	return ret;
	
	
}


bool Smtp::Connect()
{


	string sHello;
	char local_host[ 80 ];	
	if( m_bConnected )
		return true;

	if(  !m_wsSMTPServer.Initialize(PROTOCOL_TCP) )
	{
		m_szError = "Unable to create the socket.";
		return false;
	}
	if( !m_wsSMTPServer.Connect( (char*) GetServerHostName().c_str(), GetPort() ) )
	{
		m_szError =  "Unable to connect to server" ;
		m_wsSMTPServer.Close();
		return FALSE;
	}
	if( !get_response( CONNECT_SUCCESS ) )
	{
		m_szError =  "Server didn't respond." ;
		m_wsSMTPServer.Close();
		return FALSE;
	}

	gethostname( local_host, 80 );
	sHello =  "HELO ";
	sHello += local_host;
	sHello += "\r\n";

	m_wsSMTPServer.Send( (char*)sHello.c_str(), sHello.length() );
	if( !get_response( GENERIC_SUCCESS ) )
	{
		m_wsSMTPServer.Close();
		return FALSE;
	}
	m_bConnected = TRUE;
	return TRUE;

}


bool Smtp::FormatMailMessage( MailMessage* msg )
{


	assert( msg != NULL );
	if( !prepare_header( msg ) )
	{
		return false;
	}
	
	if( strncmp(msg->m_sBody.c_str() + msg->m_sBody.length() - 2, "\r\n",2) != 0 )
		msg->m_sBody += "\r\n";
	
	return true;

}


bool Smtp::SendMessage( MailMessage* msg )
{

	assert( msg != NULL );
	if( !m_bConnected )
	{
		m_szError =  "Must be connected" ;
		return false;
	}
	if( !FormatMailMessage( msg )  )
	{
		return false;
	}
	if( !transmit_message( msg ) )
	{
		return false;
	}
	return true;
}


string Smtp::GetServerHostName()
{



	return m_sSMTPServerHostName;

}


bool Smtp::get_response( uint response_expected )
{
	
	
	
	assert( response_expected >= GENERIC_SUCCESS );
	assert( response_expected < LAST_RESPONSE );
	
	string sResponse;
	uint response;
	response_code* pResp;	// Shorthand
	
	if( m_wsSMTPServer.Recv( response_buf, RESPONSE_BUFFER_SIZE ) == SOCKET_ERROR )
	{
		m_szError = "Socket Error" ;
		return false;
	}
	sResponse = response_buf;
	char szResult[8] = {0};
	strncpy(szResult,sResponse.c_str(),3);
	sscanf( szResult, "%d", &response );
	pResp = &response_table[ response_expected ];
	if( response != pResp->nResponse )
	{
		char szError[32] = {0};
		sprintf(szError,"%d:%s", response, pResp->sMessage);
		m_szError = szError;
		return false;
	}
	return true;
	
}
	
bool Smtp::transmit_message( MailMessage* msg )
{


	string sFrom;
	string sTo;
	string sTemp;
	string sEmail;

	assert( msg != NULL );
	if( !m_bConnected )
	{
		m_szError =  "Must be connected" ;
		return false;
	}


	string szMailAddress,szTemp;
	msg->GetFrom(szMailAddress,szTemp);
	sFrom  =  "MAIL From: <";
	sFrom += szMailAddress;
	sFrom += ">\r\n";
	m_wsSMTPServer.Send( (char*)sFrom.c_str(), sFrom.length());
	
	if( !get_response( GENERIC_SUCCESS ) && !Authentication() )
		return false;
	

	for( int i = 0; i < msg->GetNumRecipients(); i++ )
	{
		msg->GetRecipient( sEmail, sTemp, i );
		sTo  =  "RCPT TO: <";
		sTo +=	sEmail;
		sTo += ">\r\n";
		m_wsSMTPServer.Send( (char*)sTo.c_str(), sTo.length() );
		get_response( GENERIC_SUCCESS );
	}


	sTemp = "DATA\r\n";
	m_wsSMTPServer.Send( (char*)sTemp.c_str(), sTemp.length() );
	if( !get_response( DATA_SUCCESS ) )
	{
		return false;
	}

	m_wsSMTPServer.Send( (char*)msg->m_sHeader.c_str(), msg->m_sHeader.length() );


	sTemp = prepare_body( msg );
	m_wsSMTPServer.Send( (char*)sTemp.c_str(), sTemp.length() );


	sTemp = "\r\n.\r\n";
	m_wsSMTPServer.Send( (char*)sTemp.c_str(), sTemp.length() );
	if( !get_response( GENERIC_SUCCESS ) )
	{
		return false;
	}
	return true;
}


string Smtp::prepare_body( MailMessage* msg )
{

	assert( msg != NULL );
	string sTemp;
	string sCooked = "";
	const char* szBad = "\r\n.\r\n";
	const char* szGood = "\r\n..\r\n";

	sTemp = msg->m_sBody;
	if( strncmp(sTemp.c_str(),".\r\n",3) == 0)
		sTemp = "." + sTemp;

	char* p = NULL;

	char *pBody = new char[msg->m_sBody.length() + 1];
	strcpy(pBody,msg->m_sBody.c_str());
	*(pBody + msg->m_sBody.length()) = '\0';

	char* pPos = pBody;
	while( (p = strstr(pPos, szBad )) != NULL )
	{
		*p = '\0';
		sCooked = p;
		sCooked += szGood;
		sTemp += sCooked;
		pPos = p + strlen(szBad);
	}

	delete []pBody;
	pBody = NULL;
	
	return sTemp;
}


bool Smtp::prepare_header( MailMessage* msg)
{

	assert( msg != NULL );
	string sFrom;
	string sTo;
	char szDate[64] = {0};
	string& sHeader = msg->m_sHeader;	// Shorthand

	if( msg->GetNumRecipients() <= 0 )
	{
		m_szError = "No Recipients";
		return false;
	}

	sHeader = "";	// Clear it

	// Get the recipients into a single string
	sTo = "";
	string sEmail = "";
	string sFriendly = "";
	for( int i = 0; i < msg->GetNumRecipients(); i++ )
	{
		msg->GetRecipient( sEmail, sFriendly, i );
		sTo += ( i > 0 ? "," : "" );
		sTo += sFriendly;
		sTo += "<";
		sTo += sEmail;
		sTo += ">";
	}
	msg->m_tDateTime = time(NULL);
	// Format: Mon, 01 Jun 98 01:10:30 GMT

	string szMail,szUser,szFrom;
	msg->GetFrom(szMail,szUser);
	
	if(!szUser.empty())
	{
		szFrom  = szUser;
		szFrom += "<" ;
		szFrom += szMail;
		szFrom += ">";
	}
	else
	{
		szFrom = szMail;
	}
	char * pszFormat = "%a, %d %b %y %H:%M:%S %Z";
	strftime(szDate,64,pszFormat,localtime(&msg->m_tDateTime));

	sHeader  = "Date: ";
	sHeader += szDate;
	sHeader += "\r\n";
	sHeader += "From: ";
	sHeader += szFrom;
	sHeader += "\r\n";
	sHeader += "To: ";
	sHeader += sTo;
	sHeader += "\r\n";
	sHeader += "Subject: ";
	sHeader += msg->m_sSubject;
	sHeader += "\r\n";
	sHeader += "X-Mailer: <";
	sHeader += m_sMailerName;
	sHeader += ">\r\n\r\n";
	return true;
}


bool Smtp::Authentication(string user,string password)
{
	
	

	   
	m_wsSMTPServer.Send( (char*)user.c_str(), user.length() );
	if( !get_response(USERNAME_SUCCESS) )
	{
		m_szError  = "USERNAME FAILURE";
		return false;
	}
    
	m_wsSMTPServer.Send( (char*)password.c_str(), password.length() );	
	if( !get_response(LOGIN_SUCCESS) )
	{
		m_szError = "Login failure";
		return false; 
		
	}

	return true;
	
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -