SMTP Protocol wrapper class

Email is the most popular media for communication on Internet. This application is consist of two protocols,

  • POP 3

POP 3 protocol is usually used for retriving mail from email server (which is a POP server). I allready submitted a class which wrapper the POP 3 protocol. For official description of the protocol you can consult with RFC 1225.

  • SMTP

SMTP (Simple Mail Transfer Protocol) is used for sending email to it destination. For details about SMTP protocol you can refere to RCF 821 . My new contribution is wrapper class for SMTP protocol. I did not completely implemented the SMTP protocol but you can used it in any application which is sending mail through SMTP protocol.

This class has several methods. I choice the names of the methods same as the SMTP commands, so that it can be easily understandable. In this class again I used CSocket as class member (surperise not inherent it), so that I can used it in Threads. Following is code of the class with comments.

//////////////////////////////////////////////////////////////////////
// SMTP.h: interface for the CSMTP class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_SMTP_H__617F7E82_7F4D_11D1_88A0_00001C302581__INCLUDED_)
#define AFX_SMTP_H__617F7E82_7F4D_11D1_88A0_00001C302581__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000

#define CONNECTION_CHECK 0
#define HELLO_CHECK 1
#define MAIL_CHECK 2
#define RCPT_CHECK 3
#define DATA_START_CHECK 4
#define DATA_END_CHECK 5
#define QUIT_CHECK 6
#define DATA_CHECK 7


class CSMTP 
{
public:
	BOOL Mail(); // 
	CString GetErrorMessage();
	BOOL Data(CString Subject, CString Body);
	CString GetTo();
	BOOL SetTo(CString to);
	CString GetFrom();
	void SetFrom(CString from);
	BOOL Mail(CString from);
	BOOL Disconnect();
	CString GetHost();
	void SetHost(CString Host);
	BOOL Connect(CString Host, CString Me);
	BOOL Connect();
	CSMTP();
	virtual ~CSMTP();
	
private:
	CString GetError(CString Response);
	CString m_ErrorMessage;
	BOOL CheckResponse(int Type);
	int m_NoOfTo;
	CStringArray m_To;
	CString m_From;
	CSocket m_SMTPServer;
	CString m_Host;
   };

#endif // !defined(AFX_SMTP_H__617F7E82_7F4D_11D1_88A0_00001C302581__INCLUDED_)


//////////////////////////////////////////////////////////////////////////
// SMTP.cpp: implementation of the CSMTP class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "MailSend.h"
#include "SMTP.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CSMTP::CSMTP()
{
	m_NoOfTo = 0;
	m_SMTPServer.Create();
}

CSMTP::~CSMTP()
{
	m_SMTPServer.Close();
}

// Connect to the SMTP Server
BOOL CSMTP::Connect()
{
	return Connect(m_Host,m_From);
}

// Connect to the SMTP Server
BOOL CSMTP::Connect(CString Host,CString From)
{
	if (!m_SMTPServer.Connect(Host,25)) // 25 for SMTP Port
	{
		m_ErrorMessage = _T("Server cannot be connected");
		return FALSE;
	}
	else
	{
		if(CheckResponse(CONNECTION_CHECK)==FALSE)
			return FALSE;
		
		char buf [512];
		
		wsprintf (buf, "HELO %s\r\n", (LPCSTR) From);
		m_SMTPServer.Send(buf, strlen (buf)); 
		if (CheckResponse(HELLO_CHECK)==FALSE)
			return FALSE;
		else 
			return TRUE; 
		
		return TRUE;
	}
}

// Setting the Host String
void CSMTP::SetHost(CString Host)
{
	m_Host = Host;
}

// Returing the Host String
CString CSMTP::GetHost()
{
	return m_Host;
}

// Sending the "QUIT" command to the SMTP Server
BOOL CSMTP::Disconnect()
{
	char buf[256];
	
	wsprintf (buf, "QUIT \r\n");
	m_SMTPServer.Send(buf, strlen (buf)); 
	if (CheckResponse(QUIT_CHECK)==FALSE)
		return FALSE;
	else 
		return TRUE;
}

// Sending the "MAIL" command to the SMTP Server
BOOL CSMTP::Mail(CString from)
{
	char buf[256];
	
	wsprintf (buf, "MAIL From:<%s>\r\n", (LPCSTR) from);
	m_SMTPServer.Send(buf, strlen (buf)); 
	if (CheckResponse(MAIL_CHECK)==FALSE)
		return FALSE;
	else 
		return TRUE; 
}

// Setting the From string
void CSMTP::SetFrom(CString from)
{
	m_From = from;
}

// Returing the From string
CString CSMTP::GetFrom()
{
	return m_From;
}

// Setting the TO string
BOOL CSMTP::SetTo(CString to)
{
	char buf[256];
	m_To.Add(to); // Saving vale of to
	
	wsprintf (buf, "RCPT TO:<%s>\r\n", (LPCSTR) to);
	m_SMTPServer.Send(buf, strlen (buf)); 
	if (CheckResponse(RCPT_CHECK)==FALSE)
		return FALSE;
	else 
		return TRUE; 
	
}

// Returing the TO string
CString CSMTP::GetTo()
{ 
	if(m_To.GetSize()>=m_NoOfTo)
	{
		m_NoOfTo++;
		return m_To[m_NoOfTo-1];
	}
	else
		return _T("No more To available");
}

// Sending the "DATA" command to the SMTP Server
BOOL CSMTP::Data(CString Subject, CString Body)
{
	char buf[256];
	
	wsprintf (buf, "DATA\r\n");
	
	m_SMTPServer.Send(buf, strlen (buf)); 
	if (CheckResponse(DATA_CHECK)==FALSE)
		return FALSE;
	else 
	{
		wsprintf (buf, "SUBJECT:%s\r\n", (LPCSTR) Subject);
		m_SMTPServer.Send(buf, strlen (buf)); 
		
		wsprintf (buf, "%s\r\n", (LPCSTR) Body);
		m_SMTPServer.Send(buf, strlen (buf)); 
		
		wsprintf (buf, ".\r\n");
		m_SMTPServer.Send(buf, strlen (buf)); 
		
		return TRUE;
	}
}

// This methods checks the response from the 
// Server
BOOL CSMTP::CheckResponse(int Type)
{
	char buf [1000];
	char temp[3];
	
	for (int i=0;i < 512;i++)
		buf[i]='\0';
	
	// Receive the data from Server
	m_SMTPServer.Receive(buf, sizeof(buf));
	strncpy(temp,buf,3);
	int temp2 = atoi(temp);
	switch (Type)
	{
	case CONNECTION_CHECK:
		if (temp2 != 220)
		{
			m_ErrorMessage = GetError((LPCTSTR)buf);
			return FALSE;
		} 
		break;
		
	case HELLO_CHECK:
		if (temp2 != 250)
		{
			m_ErrorMessage = GetError((LPCTSTR)buf);
			return FALSE;
		} 
		break;
	case MAIL_CHECK:
		if (temp2 != 250)
		{
			m_ErrorMessage = GetError((LPCTSTR)buf);
			return FALSE;
		} 
		break;
	case RCPT_CHECK:
		if (temp2 != 250)
		{
			m_ErrorMessage = GetError((LPCTSTR)buf);
			return FALSE;
		} 
		break;
	case DATA_START_CHECK:
		if (temp2 != 354)
		{
			m_ErrorMessage = GetError((LPCTSTR)buf);
			return FALSE;
		} 
		break;
	case DATA_END_CHECK:
		if (temp2 != 250)
		{
			m_ErrorMessage = GetError((LPCTSTR)buf);
			return FALSE;
		} 
		break;
	case QUIT_CHECK:
		if (temp2 != 221)
		{
			m_ErrorMessage = GetError((LPCTSTR)buf);
			return FALSE;
		} 
		break;
	case DATA_CHECK:
		if (temp2 != 354)
		{
			m_ErrorMessage = GetError((LPCTSTR)buf);
			return FALSE;
		} 
		break;
		
	}
	return TRUE;
}

// Returing the Error Message
CString CSMTP::GetErrorMessage()
{
	return m_ErrorMessage;
}

// Preparing the Error Message according to 
// Error Number
CString CSMTP::GetError(CString Response)
{
	if(Response.Find("211"))
		return _T("System status or system help reply");
	if(Response.Find("214"))
		return _T("Help Message");
	if(Response.Find("220"))
		return _T("Service is ready");
	if(Response.Find("221"))
		return _T("Service closing transmission channel");
	if(Response.Find("250"))
		return _T("Requested mail action okay, completed");
	if(Response.Find("251"))
		return _T("user not local: will forward to forward path");
	if(Response.Find("354"))
		return _T("Start mail input; end with <CRLF>.<CRLF>");
	
	return _T("No Error Number is matched with ")+Response;
}

// Just overloading of the Mail method
BOOL CSMTP::Mail()
{
	return Mail(m_From);
}
Here the samll implementation of the class,
CSMTP m_smtp;
m_smtp.Connect("khi.compol.com","aasif@khi.compol.com");
m_smtp.Mail("aasif@khi.compol.com");
m_smtp.SetTo("zafir@home.com");
m_smtp.Data("test message","This is a test message ... ");
m_smtp.Disconnect(); 



Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: October 29, 2014 @ 11:00 a.m. ET / 8:00 a.m. PT Are you interested in building a cognitive application using the power of IBM Watson? Need a platform that provides speed and ease for rapidly deploying this application? Join Chris Madison, Watson Solution Architect, as he walks through the process of building a Watson powered application on IBM Bluemix. Chris will talk about the new Watson Services just released on IBM bluemix, but more importantly he will do a step by step cognitive …

  • A modern mobile IT strategy is no longer an option, it is an absolute business necessity. Today's most productive employees are not tied to a desk, an office, or a location. They are mobile. And your company's IT strategy has to be ready to support them with easy, reliable, 24/7 access to the business information they need, from anywhere in the world, across a broad range of communication devices. Here's how some of the nation's most progressive corporations are meeting the many needs of their mobile workers …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds