Showing posts with label boost. Show all posts
Showing posts with label boost. 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!");





Saturday, July 28, 2012

My experience on C++ Serialization Solutions

Recently I tried 3 solutions for serializing request data in my Apache filter module in C++:
1- Google Protocol Buffer
2- boost serialization
3- msgpack
I was disappointed of using solutions 1 and 2 because of errors I faced. I submitted errors in many forums and related mailing lists, but I couldn't get any answer.
Google protocol buffer seems professional but It needs classes to be defined in specific way which that protocol forces.
BTW I started with this solution and designed *.protoc files and generated my model files.
the solutions worked fine in a console application but I've got segmentation fault in Apache module without any specific error. ( I tried debugging with gdb, ddd,.... but no chance to resolve the error).
So I switched to boost serialization. It was much simpler than Google solution but It didn't work completely.
It worked fine in console application and Apache filter too.
but I've segfault when I tried to serialize nested classes.
I returned to my mind, searching a solution recommended by one of my friends( Kamyar, which has been used that solution in .NET).
It was msgpack, the 3rd solution.
It's much simple than Google solution and even simpler than boost serialization.
It worked fine without any headache. As msgpack website says, It's much fast from Google and boost solution :
http://www.msgpack.org

Showing posts with label boost. Show all posts
Showing posts with label boost. 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!");





Saturday, July 28, 2012

My experience on C++ Serialization Solutions

Recently I tried 3 solutions for serializing request data in my Apache filter module in C++:
1- Google Protocol Buffer
2- boost serialization
3- msgpack
I was disappointed of using solutions 1 and 2 because of errors I faced. I submitted errors in many forums and related mailing lists, but I couldn't get any answer.
Google protocol buffer seems professional but It needs classes to be defined in specific way which that protocol forces.
BTW I started with this solution and designed *.protoc files and generated my model files.
the solutions worked fine in a console application but I've got segmentation fault in Apache module without any specific error. ( I tried debugging with gdb, ddd,.... but no chance to resolve the error).
So I switched to boost serialization. It was much simpler than Google solution but It didn't work completely.
It worked fine in console application and Apache filter too.
but I've segfault when I tried to serialize nested classes.
I returned to my mind, searching a solution recommended by one of my friends( Kamyar, which has been used that solution in .NET).
It was msgpack, the 3rd solution.
It's much simple than Google solution and even simpler than boost serialization.
It worked fine without any headache. As msgpack website says, It's much fast from Google and boost solution :
http://www.msgpack.org