Showing posts with label SMTP. Show all posts
Showing posts with label SMTP. Show all posts

Saturday, August 11, 2012

Send Email in C++ ( SMTP Client in C++ )

Boost! Yes! It's a good library for you to help you develop cross-platform C++ applications; headache free. among all libraries in boost, boost::asio is for implementing asynchronous input output operations and working with network. After having a look at boost asio samples and SMTP RFC : http://www.ietf.org/rfc/rfc2821.txt I implemented this simple class to be used in your C++ programs.
the only tricky part is base64 encoding which is required for sending user/password to SMTP Server.
#include <iostream>
#include <istream>
#include <ostream>
#include <string>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/archive/iterators/base64_from_binary.hpp>
#include <boost/archive/iterators/transform_width.hpp>
#include <boost/archive/iterators/ostream_iterator.hpp>
using boost::asio::ip::tcp;
using namespace boost::archive::iterators;
typedef base64_from_binary<transform_width<const char *,6,8> > base64_text;
class SMTPClient
{
public:
 SMTPClient(std::string pServer,unsigned int pPort,std::string pUser,std::string pPassword):
   mServer(pServer),mPort(pPort),mUserName(pUser),mPassword(pPassword),mSocket(mIOService),mResolver(mIOService)
   {
    tcp::resolver::query qry(mServer,boost::lexical_cast<std::string>( mPort ));
    mResolver.async_resolve(qry,boost::bind(&SMTPClient::handleResolve,this,boost::asio::placeholders::error,
     boost::asio::placeholders::iterator));
   }
   bool Send(std::string pFrom,std::string pTo,std::string pSubject,std::string pMessage)
   {
    mFrom=pFrom;
    mTo=pTo;
    mSubject=pSubject;
    mMessage=pMessage;
    mIOService.run();
    return mHasError;
   }
private:
 std::string encodeBase64(std::string pData)
 {
  std::stringstream os;
  size_t sz=pData.size();
  std::copy(base64_text(pData.c_str()),base64_text(pData.c_str()+sz),ostream_iterator<char>(os));
  return os.str();
 }
 void handleResolve(const boost::system::error_code& err,tcp::resolver::iterator endpoint_iterator)
 {
  if(!err)
  {
   tcp::endpoint endpoint=*endpoint_iterator;
   mSocket.async_connect(endpoint,
    boost::bind(&SMTPClient::handleConnect,this,boost::asio::placeholders::error,++endpoint_iterator));
  }
  else
  {
   mHasError=true;
   mErrorMsg= err.message();
  }
 }
 void writeLine(std::string pData)
 {
  std::ostream req_strm(&mRequest);
  req_strm << pData << "\r\n";
  boost::asio::write(mSocket,mRequest);
  req_strm.clear();
 }
 void handleConnect(const boost::system::error_code& err,tcp::resolver::iterator endpoint_iterator)
 {
  if (!err)
  {
   // The connection was successful. Send the request.
   std::ostream req_strm(&mRequest);
   writeLine("EHLO "+mServer);
   writeLine("AUTH LOGIN");
   writeLine(encodeBase64(mUserName));
   writeLine(encodeBase64(mPassword));
   writeLine( "MAIL FROM:<"+mFrom+">");
   writeLine( "RCPT TO:<"+mTo+">");
   writeLine( "DATA");
   writeLine( "SUBJECT:"+mSubject);
   writeLine( "From:"+mFrom);
   writeLine( "To:"+mTo);
   writeLine( "");
   writeLine( mMessage );
   writeLine( ".\r\n");
  }
  else
  {
   mHasError=true;
   mErrorMsg= err.message();
  }
 }
 std::string mServer;
 std::string mUserName;
 std::string mPassword;
 std::string mFrom;
 std::string mTo;
 std::string mSubject;
 std::string mMessage;
 unsigned int mPort;
 boost::asio::io_service mIOService;
 tcp::resolver mResolver;
 tcp::socket mSocket;
 boost::asio::streambuf mRequest;
 boost::asio::streambuf mResponse;
 bool mHasError;
 std::string mErrorMsg;

};
Yest ! that's it. you are free to copy and paste this code into your application:
SMTPClient mailc("yoursmtpserver.com",25,"[email protected]","password");
mailc.Send("[email protected]","[email protected]","subject","Hello from C++ SMTP Client!");





Showing posts with label SMTP. Show all posts
Showing posts with label SMTP. Show all posts

Saturday, August 11, 2012

Send Email in C++ ( SMTP Client in C++ )

Boost! Yes! It's a good library for you to help you develop cross-platform C++ applications; headache free. among all libraries in boost, boost::asio is for implementing asynchronous input output operations and working with network. After having a look at boost asio samples and SMTP RFC : http://www.ietf.org/rfc/rfc2821.txt I implemented this simple class to be used in your C++ programs.
the only tricky part is base64 encoding which is required for sending user/password to SMTP Server.
#include <iostream>
#include <istream>
#include <ostream>
#include <string>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/archive/iterators/base64_from_binary.hpp>
#include <boost/archive/iterators/transform_width.hpp>
#include <boost/archive/iterators/ostream_iterator.hpp>
using boost::asio::ip::tcp;
using namespace boost::archive::iterators;
typedef base64_from_binary<transform_width<const char *,6,8> > base64_text;
class SMTPClient
{
public:
 SMTPClient(std::string pServer,unsigned int pPort,std::string pUser,std::string pPassword):
   mServer(pServer),mPort(pPort),mUserName(pUser),mPassword(pPassword),mSocket(mIOService),mResolver(mIOService)
   {
    tcp::resolver::query qry(mServer,boost::lexical_cast<std::string>( mPort ));
    mResolver.async_resolve(qry,boost::bind(&SMTPClient::handleResolve,this,boost::asio::placeholders::error,
     boost::asio::placeholders::iterator));
   }
   bool Send(std::string pFrom,std::string pTo,std::string pSubject,std::string pMessage)
   {
    mFrom=pFrom;
    mTo=pTo;
    mSubject=pSubject;
    mMessage=pMessage;
    mIOService.run();
    return mHasError;
   }
private:
 std::string encodeBase64(std::string pData)
 {
  std::stringstream os;
  size_t sz=pData.size();
  std::copy(base64_text(pData.c_str()),base64_text(pData.c_str()+sz),ostream_iterator<char>(os));
  return os.str();
 }
 void handleResolve(const boost::system::error_code& err,tcp::resolver::iterator endpoint_iterator)
 {
  if(!err)
  {
   tcp::endpoint endpoint=*endpoint_iterator;
   mSocket.async_connect(endpoint,
    boost::bind(&SMTPClient::handleConnect,this,boost::asio::placeholders::error,++endpoint_iterator));
  }
  else
  {
   mHasError=true;
   mErrorMsg= err.message();
  }
 }
 void writeLine(std::string pData)
 {
  std::ostream req_strm(&mRequest);
  req_strm << pData << "\r\n";
  boost::asio::write(mSocket,mRequest);
  req_strm.clear();
 }
 void handleConnect(const boost::system::error_code& err,tcp::resolver::iterator endpoint_iterator)
 {
  if (!err)
  {
   // The connection was successful. Send the request.
   std::ostream req_strm(&mRequest);
   writeLine("EHLO "+mServer);
   writeLine("AUTH LOGIN");
   writeLine(encodeBase64(mUserName));
   writeLine(encodeBase64(mPassword));
   writeLine( "MAIL FROM:<"+mFrom+">");
   writeLine( "RCPT TO:<"+mTo+">");
   writeLine( "DATA");
   writeLine( "SUBJECT:"+mSubject);
   writeLine( "From:"+mFrom);
   writeLine( "To:"+mTo);
   writeLine( "");
   writeLine( mMessage );
   writeLine( ".\r\n");
  }
  else
  {
   mHasError=true;
   mErrorMsg= err.message();
  }
 }
 std::string mServer;
 std::string mUserName;
 std::string mPassword;
 std::string mFrom;
 std::string mTo;
 std::string mSubject;
 std::string mMessage;
 unsigned int mPort;
 boost::asio::io_service mIOService;
 tcp::resolver mResolver;
 tcp::socket mSocket;
 boost::asio::streambuf mRequest;
 boost::asio::streambuf mResponse;
 bool mHasError;
 std::string mErrorMsg;

};
Yest ! that's it. you are free to copy and paste this code into your application:
SMTPClient mailc("yoursmtpserver.com",25,"[email protected]","password");
mailc.Send("[email protected]","[email protected]","subject","Hello from C++ SMTP Client!");