smtp_Email
所属分类:Email客户端
开发工具:Visual C++
文件大小:4498KB
下载次数:22
上传日期:2012-03-19 10:50:36
上 传 者:
cameloanthony
说明: 利用SMTP实现收发邮件,程序证明可实现
(Use SMTP to send and receive mail, the program proved to be achieved)
文件列表:
smtp收发邮件 (0, 2012-02-22)
smtp收发邮件\AttachDlg.cpp (1757, 1998-10-19)
smtp收发邮件\AttachDlg.h (1272, 1998-10-19)
smtp收发邮件\CSmtp.cpp (26435, 2001-10-11)
smtp收发邮件\CSmtp.h (7632, 1998-10-19)
smtp收发邮件\Debug (0, 2012-02-22)
smtp收发邮件\Debug\AttachDlg.obj (18452, 2012-02-22)
smtp收发邮件\Debug\CSmtp.obj (187878, 2012-02-22)
smtp收发邮件\Debug\MainFrm.obj (20664, 2012-02-22)
smtp收发邮件\Debug\SmtpSetupDlg.obj (17734, 2012-02-22)
smtp收发邮件\Debug\StdAfx.obj (105527, 2012-02-22)
smtp收发邮件\Debug\smtp.exe (180295, 2012-02-22)
smtp收发邮件\Debug\smtp.ilk (486724, 2012-02-22)
smtp收发邮件\Debug\smtp.obj (22131, 2012-02-22)
smtp收发邮件\Debug\smtp.pch (5479424, 2012-02-22)
smtp收发邮件\Debug\smtp.pdb (467968, 2012-02-22)
smtp收发邮件\Debug\smtp.res (9612, 2012-02-22)
smtp收发邮件\Debug\smtpDoc.obj (33428, 2012-02-22)
smtp收发邮件\Debug\smtpView.obj (23937, 2012-02-22)
smtp收发邮件\Debug\vc60.idb (222208, 2012-02-22)
smtp收发邮件\Debug\vc60.pdb (372736, 2012-02-22)
smtp收发邮件\MainFrm.cpp (2479, 1998-11-21)
smtp收发邮件\MainFrm.h (1608, 1998-11-21)
smtp收发邮件\Release (0, 2012-02-22)
smtp收发邮件\Release\AttachDlg.obj (15238, 2001-11-27)
smtp收发邮件\Release\CSmtp.obj (81016, 2001-11-27)
smtp收发邮件\Release\MainFrm.obj (13053, 2001-11-27)
smtp收发邮件\Release\SmtpSetupDlg.obj (12580, 2001-11-27)
smtp收发邮件\Release\StdAfx.obj (786, 2001-11-27)
smtp收发邮件\Release\smtp.exe (61440, 2001-11-27)
smtp收发邮件\Release\smtp.obj (16048, 2001-11-27)
smtp收发邮件\Release\smtp.pch (5597692, 2001-11-27)
smtp收发邮件\Release\smtp.res (9612, 2001-11-27)
smtp收发邮件\Release\smtpDoc.obj (20461, 2001-11-27)
smtp收发邮件\Release\smtpView.obj (18693, 2001-11-27)
smtp收发邮件\Release\vc60.idb (58368, 2005-05-25)
smtp收发邮件\Smtp.cpp (4060, 1998-10-19)
smtp收发邮件\Smtp.h (1343, 1998-10-19)
smtp收发邮件\SmtpSetupDlg.cpp (1775, 1998-10-19)
... ...
#include
#include "MailMessage.h"
#define SMTP_PORT 25 // Standard port for SMTP servers
#define RESPONSE_BUFFER_SIZE 1024
class CSMTP
{
public:
CSMTP( LPCTSTR szSMTPServerName, UINT nPort = SMTP_PORT );
virtual ~CSMTP();
void SetServerProperties( LPCTSTR szSMTPServerName, UINT nPort = SMTP_PORT );
CString GetLastError();
UINT GetPort();
BOOL Disconnect();
BOOL Connect();
virtual BOOL FormatMailMessage( CMailMessage* msg );
BOOL SendMessage( CMailMessage* msg );
CString GetServerHostName();
private:
BOOL get_response( UINT response_expected );
CString cook_body( CMailMessage* msg );
CString m_sError;
BOOL m_bConnected;
UINT m_nPort;
CString m_sSMTPServerHostName;
CSocket m_wsSMTPServer;
protected:
virtual BOOL transmit_message( CMailMessage* msg );
//
// Helper Code
//
struct response_code
{
UINT nResponse; // Response we're looking for
TCHAR* sMessage; // Error message if we don't get it
};
enum eResponse
{
GENERIC_SUCCESS = 0,
CONNECT_SUCCESS,
DATA_SUCCESS,
QUIT_SUCCESS,
// Include any others here
LAST_RESPONSE // Do not add entries past this one
};
TCHAR *response_buf;
static response_code response_table[];
};
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
// Static member initializers
//
// Note: the order of the entries is important.
// They must be synchronized with eResponse entries.
CSMTP::response_code CSMTP::response_table[] =
{
// GENERIC_SUCCESS
{ 250, _T( "SMTP server error" ) },
// CONNECT_SUCCESS
{ 220, _T( "SMTP server not available" ) },
// DATA_SUCCESS
{ 354, _T( "SMTP server not ready for data" ) },
// QUIT_SUCCESS
{ 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;
}
BOOL CSMTP::Connect()
{
CString sHello;
TCHAR local_host[ 80 ]; // Warning: arbitrary size
if( m_bConnected )
return TRUE;
try
{
// This will be deleted in Disconnect();
response_buf = new TCHAR[ RESPONSE_BUFFER_SIZE ];
// I can't count on all class users' applications
// to have exception-throwing operator-new implementations,
// so I'll soul-kiss the ones that don't.
if( response_buf == NULL )
{
m_sError = _T( "Not enough memory" );
return FALSE;
}
}
catch( CException *e )
{
response_buf = NULL;
m_sError = _T( "Not enough memory" );
delete e;
return FALSE;
}
if( !m_wsSMTPServer.Create() )
{
m_sError = _T( "Unable to create the socket." );
delete response_buf;
response_buf = NULL;
return FALSE;
}
if( !m_wsSMTPServer.Connect( GetServerHostName(), GetPort() ) )
{
m_sError = _T( "Unable to connect to server" );
m_wsSMTPServer.Close();
delete response_buf;
response_buf = NULL;
return FALSE;
}
if( !get_response( CONNECT_SUCCESS ) )
{
m_sError = _T( "Server didn't respond." );
m_wsSMTPServer.Close();
delete response_buf;
response_buf = NULL;
return FALSE;
}
gethostname( local_host, 80 );
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 ret;
if( !m_bConnected )
return TRUE;
// Disconnect gracefully from the server and close the socket
CString sQuit = _T( "QUIT\r\n" );
m_wsSMTPServer.Send( (LPCTSTR)sQuit, sQuit.GetLength() );
// No need to check return value here.
// If it fails, the message is available with GetLastError
ret = get_response( QUIT_SUCCESS );
m_wsSMTPServer.Close();
if( response_buf != NULL )
{
delete[] response_buf;
response_buf = NULL;
}
m_bConnected = FALSE;
return ret;
}
UINT CSMTP::GetPort()
{
return m_nPort;
}
CString CSMTP::GetLastError()
{
return m_sError;
}
BOOL CSMTP::SendMessage(CMailMessage * msg)
{
ASSERT( msg != NULL );
if( !m_bConnected )
{
m_sError = _T( "Must be connected" );
return FALSE;
}
if( FormatMailMessage( msg ) == FALSE )
{
return FALSE;
}
if( transmit_message( msg ) == FALSE )
{
return FALSE;
}
return TRUE;
}
BOOL CSMTP::FormatMailMessage( CMailMessage* msg )
{
ASSERT( msg != NULL );
if( msg->GetNumRecipients() == 0 )
{
m_sError = _T( "No Recipients" );
return FALSE;
}
msg->FormatMessage();
return TRUE;
}
void CSMTP::SetServerProperties( LPCTSTR szSMTPServerName, UINT nPort)
{
ASSERT( szSMTPServerName != NULL );
// Needs to be safe in non-debug too
if( szSMTPServerName == NULL )
return;
m_sSMTPServerHostName = szSMTPServerName;
m_nPort = nPort;
}
CString CSMTP::cook_body(CMailMessage * msg)
{
ASSERT( msg != NULL );
CString sTemp;
CString sCooked = _T( "" );
LPTSTR szBad = _T( "\r\n.\r\n" );
LPTSTR szGood = _T( "\r\n..\r\n" );
int nPos;
int nStart = 0;
int nBadLength = strlen( szBad );
sTemp = msg->m_sBody;
if( sTemp.Left( 3 ) == _T( ".\r\n" ) )
sTemp = _T( "." ) + sTemp;
//
// This is a little inefficient because it beings a search
// at the beginning of the string each time. This was
// the only thing I could think of that handled ALL variations.
// In particular, the sequence "\r\n.\r\n.\r\n" is troublesome.
// (Even CStringEx's FindReplace wouldn't handle that situation
// with the global flag set.)
//
while( (nPos = sTemp.Find( szBad )) > -1 )
{
sCooked = sTemp.Mid( nStart, nPos );
sCooked += szGood;
sTemp = sCooked + sTemp.Right( sTemp.GetLength() - (nPos + nBadLength) );
}
return sTemp;
}
BOOL CSMTP::transmit_message(CMailMessage * msg)
{
CString sFrom;
CString sTo;
CString sTemp;
CString sEmail;
ASSERT( msg != NULL );
if( !m_bConnected )
{
m_sError = _T( "Must be connected" );
return FALSE;
}
// Send the MAIL command
//
sFrom.Format( _T( "MAIL From: <%s>\r\n" ), (LPCTSTR)msg->m_sFrom );
m_wsSMTPServer.Send( (LPCTSTR)sFrom, sFrom.GetLength() );
if( !get_response( GENERIC_SUCCESS ) )
return FALSE;
// Send RCPT commands (one for each recipient)
//
for( int i = 0; i < msg->GetNumRecipients(); i++ )
{
msg->GetRecipient( sEmail, sTemp, i );
sTo.Format( _T( "RCPT TO: <%s>\r\n" ), (LPCTSTR)sEmail );
m_wsSMTPServer.Send( (LPCTSTR)sTo, sTo.GetLength() );
get_response( GENERIC_SUCCESS );
}
// Send the DATA command
sTemp = _T( "DATA\r\n" );
m_wsSMTPServer.Send( (LPCTSTR)sTemp, sTemp.GetLength() );
if( !get_response( DATA_SUCCESS ) )
{
return FALSE;
}
// Send the header
//
m_wsSMTPServer.Send( (LPCTSTR)msg->m_sHeader, msg->m_sHeader.GetLength() );
// Send the body
//
sTemp = cook_body( msg );
m_wsSMTPServer.Send( (LPCTSTR)sTemp, sTemp.GetLength() );
// Signal end of data
//
sTemp = _T( "\r\n.\r\n" );
m_wsSMTPServer.Send( (LPCTSTR)sTemp, sTemp.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; // Shorthand
if( m_wsSMTPServer.Receive( response_buf, RESPONSE_BUFFER_SIZE ) == SOCKET_ERROR )
{
m_sError = _T( "Socket Error" );
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;
}
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
#include
// CMailMessage
// Formats a message compliant with RFC 822.
//
class CMailMessage
{
public:
CMailMessage();
virtual ~CMailMessage();
void FormatMessage();
int GetNumRecipients();
BOOL GetRecipient( CString& sEmailAddress, CString& sFriendlyName, int nIndex = 0 );
BOOL AddRecipient( LPCTSTR szEmailAddress, LPCTSTR szFriendlyName = "" );
BOOL AddMultipleRecipients( LPCTSTR szRecipients = NULL );
UINT GetCharsPerLine();
void SetCharsPerLine( UINT nCharsPerLine );
CString m_sFrom;
CString m_sSubject;
CString m_sEnvelope;
CString m_sMailerName;
CString m_sHeader;
CTime m_tDateTime;
CString m_sBody;
private:
UINT m_nCharsPerLine;
class CRecipient
{
public:
CString m_sEmailAddress;
CString m_sFriendlyName;
};
CArray m_Recipients;
protected:
// When overriding prepare_header(), call base class
// version first, then add specialized
// add_header_line calls.
// This ensures that the base class has a chance to
// create the header lines it needs.
virtual void prepare_header();
virtual void prepare_body();
virtual void end_header();
virtual void start_header();
// This rarely needs overwriting, but is virtual just in case.
// Do not include the trailing CR/LF in parameter.
virtual void add_header_line( LPCTSTR szHeaderLine );
};
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CMailMessage::CMailMessage()
{
m_sMailerName = _T( "WC Mail" );
SetCharsPerLine( 76 );
}
CMailMessage::~CMailMessage()
{
}
BOOL CMailMessage::AddRecipient( LPCTSTR szEmailAddress, LPCTSTR szFriendlyName)
{
ASSERT( szEmailAddress != NULL );
ASSERT( szFriendlyName != NULL );
CRecipient to;
to.m_sEmailAddress = szEmailAddress;
to.m_sFriendlyName = szFriendlyName;
m_Recipients.Add( to );
return TRUE;
}
// sEmailAddress and sFriendlyName are OUTPUT parameters.
// If the function fails, it will return FALSE, and the OUTPUT
// parameters will not be touched.
BOOL CMailMessage::GetRecipient(CString & sEmailAddress, CString & sFriendlyName, int nIndex)
{
CRecipient to;
if( nIndex < 0 || nIndex > m_Recipients.GetUpperBound() )
return FALSE;
to = m_Recipients[ nIndex ];
sEmailAddress = to.m_sEmailAddress;
sFriendlyName = to.m_sFriendlyName;
return TRUE;
}
int CMailMessage::GetNumRecipients()
{
return m_Recipients.GetSize();
}
BOOL CMailMessage::AddMultipleRecipients(LPCTSTR szRecipients )
{
TCHAR* buf;
UINT pos;
UINT start;
CString sTemp;
CString sEmail;
CString sFriendly;
UINT length;
int nMark;
int nMark2;
ASSERT( szRecipients != NULL );
// Add Recipients
//
length = strlen( szRecipients );
buf = new TCHAR[ length + 1 ]; // Allocate a work area (don't touch parameter itself)
strcpy( buf, szRecipients );
for( pos = 0, start = 0; pos < ... ...
近期下载者:
相关文件:
收藏者: