q666123 发表于 2015-11-25 10:19:48

libcurl sendmail

  先上源码
  H
view plaincopy
[*]/*
[*] * File:   CSendMail.h
[*] * Author: jaylong35
[*] *
[*] * Created on January 16, 2012, 6:14 PM
[*] */
[*]
[*]#ifndef CSENDMAIL_H
[*]#define CSENDMAIL_H
[*]
[*]#include <string>
[*]#include <list>
[*]#include <vector>
[*]#include <curl/curl.h>
[*]
[*]#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
[*]
[*]
[*]class CSendMail {
[*]public:
[*]    CSendMail();
[*]    CSendMail(//create sendmail object with paremeter;
[*]                const std::string & strUser,
[*]                const std::string & strPsw,   
[*]                const std::string & strSmtpServer,   
[*]                int iPort,   
[*]                const std::string & strMailFrom
[*]            );
[*]    CSendMail(const CSendMail& orig);
[*]    virtual ~CSendMail();
[*]private:
[*]    std::string m_strUser;          //邮箱用户名
[*]    std::string m_strPsw;         //邮箱密码
[*]    std::string m_strSmtpServer;      //邮箱SMTP服务器
[*]    int         m_iPort;            //邮箱SMTP服务器端口
[*]    std::list<std::string> m_RecipientList;   //接收者邮件list
[*]    std::string m_strMailFrom;          //发送者邮箱
[*]    std::vector<std::string> m_MailContent;   //发送的内容队列,包括头和内容项
[*]    int         m_iMailContentPos;      //用于发送数据时记录发送到第几个content
[*]      
[*]private:
[*]    //发送内容回调函数
[*]    static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *userp);
[*]    //获取当前时间
[*]    static struct timeval tvnow(void);
[*]    //两个时间差
[*]    static long tvdiff(struct timeval newer, struct timeval older);
[*]    //创建邮件内容
[*]    bool ConstructHead(const std::string & strSubject/*邮件主题*/, const std::string & strContent/*邮件内容*/);
[*]      
[*]public:
[*]      
[*]    bool SendMail(const std::string & strSubject, const char * pMailBody, int len);
[*]    bool SendMail(const std::string & strSubject, const std::string & strMailBody);
[*]    bool SendMail(//create sendmail object with paremeter;
[*]                  const std::string & strUser,
[*]                  const std::string & strPsw,   
[*]                  const std::string & strSmtpServer,   
[*]                  int iPort,   
[*]                  std::list<std::string> & recipientList,
[*]                  const std::string & strMailFrom,
[*]                  const std::string & strSubject,   
[*]                  const char * pMailBody,   
[*]                  int len
[*]                );
[*]    bool SendMail(//create sendmail object with paremeter;
[*]                  const std::string & strUser,
[*]                  const std::string & strPsw,   
[*]                  const std::string & strSmtpServer,   
[*]                  int iPort,   
[*]                  const std::string & strMailTo,
[*]                  const std::string & strMailFrom,
[*]                  const std::string & strSubject,   
[*]                  const char * pMailBody,   
[*]                  int len
[*]                );
[*]    bool SendMail(//create sendmail object with paremeter;
[*]                  const std::string & strUser,
[*]                  const std::string & strPsw,   
[*]                  const std::string & strSmtpServer,   
[*]                  int iPort,   
[*]                  std::list<std::string> & recipientList,
[*]                  const std::string & strMailFrom,
[*]                  const std::string & strSubject,   
[*]                  const std::string & strMailBody
[*]                );
[*]    bool SendMail(//create sendmail object with paremeter;
[*]                  const std::string & strUser,
[*]                  const std::string & strPsw,   
[*]                  const std::string & strSmtpServer,   
[*]                  int iPort,   
[*]                  const std::string & strMailTo,
[*]                  const std::string & strMailFrom,
[*]                  const std::string & strSubject,   
[*]                  const std::string & strMailBody
[*]                );
[*]      
[*]    void SetUser(const std::string & strUser) { m_strUser = strUser; }
[*]    std::string & GetUser() { return m_strUser; }
[*]      
[*]    void SetPsw(const std::string & strPsw) { m_strPsw = strPsw; }
[*]    std::string & GetPsw() { return m_strPsw; }
[*]      
[*]    void SetSmtpServer(const std::string & strSmtpServer) { m_strSmtpServer = strSmtpServer; }
[*]    std::string & GetSmtpServer() { return m_strSmtpServer; }
[*]      
[*]    void SetPort(int iPort) { m_iPort = iPort; }
[*]    int GetPort() { return m_iPort; }
[*]      
[*]    void SetMailFrom(const std::string & strMailFrom) { m_strMailFrom = strMailFrom; }
[*]    std::string & GetMailFrom() { return m_strMailFrom; }
[*]      
[*]    //添加接收者邮箱
[*]    void AddRecipient(const std::string & strMailTo) { m_RecipientList.push_back(strMailTo); }
[*]    void AddRecipient(std::list<std::string> recipientList)   
[*]    {   
[*]      std::copy(recipientList.begin(), recipientList.end(), m_RecipientList.begin());
[*]    }
[*]    void ClearRecipient() { m_RecipientList.clear(); }
[*]      
[*]};
[*]
[*]
[*]#endif/* CSENDMAIL_H */
  

  cpp
view plaincopy
[*]/*
[*] * File:   CSendMail.cpp
[*] * Author: root
[*] *
[*] * Created on January 16, 2012, 6:14 PM
[*] */
[*]
[*]#include &quot;CSendMail.h&quot;
[*]
[*]CSendMail::CSendMail()   
[*]{
[*]    m_strUser = &quot;&quot;;
[*]    m_strPsw = &quot;&quot;;
[*]    m_strSmtpServer = &quot;&quot;;
[*]    m_iPort = -1;
[*]    m_RecipientList.clear();
[*]    m_strMailFrom = &quot;&quot;;
[*]    m_MailContent.clear();
[*]    m_iMailContentPos = 0;
[*]}
[*]
[*]CSendMail::CSendMail(//create sendmail object with paremeter;
[*]                const std::string & strUser,
[*]                const std::string & strPsw,   
[*]                const std::string & strSmtpServer,   
[*]                int iPort,   
[*]                const std::string & strMailFrom
[*]            )
[*]{
[*]    m_strUser = strUser;
[*]    m_strPsw = strPsw;
[*]    m_strSmtpServer = strSmtpServer;
[*]    m_iPort = iPort;
[*]    m_RecipientList.clear();
[*]    m_strMailFrom = strMailFrom;
[*]    m_MailContent.clear();
[*]    m_iMailContentPos = 0;
[*]}
[*]
[*]CSendMail::CSendMail(const CSendMail& orig) {
[*]}
[*]
[*]CSendMail::~CSendMail() {
[*]}
[*]
[*]size_t CSendMail::read_callback(void* ptr, size_t size, size_t nmemb, void* userp)
[*]{
[*]    CSendMail * pSm = (CSendMail *)userp;
[*]
[*]    if(size*nmemb < 1)
[*]      return 0;
[*]    if(pSm->m_iMailContentPos < pSm->m_MailContent.size())
[*]    {
[*]      size_t len;
[*]      len = pSm->m_MailContent.length();
[*]
[*]      memcpy(ptr, pSm->m_MailContent.c_str(), pSm->m_MailContent.length());
[*]      pSm->m_iMailContentPos&#43;&#43;; /* advance pointer */
[*]      return len;
[*]    }
[*]    return 0;
[*]}
[*]
[*]struct timeval CSendMail::tvnow()
[*]{
[*]/*
[*]** time() returns the value of time in seconds since the Epoch.
[*]*/   
[*]    struct timeval now;
[*]    now.tv_sec = (long)time(NULL);
[*]    now.tv_usec = 0;
[*]    return now;
[*]}
[*]
[*]long CSendMail::tvdiff(timeval newer, timeval older)
[*]{
[*]    return (newer.tv_sec-older.tv_sec)*1000&#43;
[*]      (newer.tv_usec-older.tv_usec)/1000;
[*]}
[*]
[*]bool CSendMail::ConstructHead(const std::string & strSubject, const std::string & strContent)
[*]{
[*]    m_MailContent.push_back(&quot;MIME-Versioin: 1.0\n&quot;);
[*]    std::string strTemp = &quot;To: &quot;;
[*]    for(std::list<std::string >::iterator it = m_RecipientList.begin(); it != m_RecipientList.end();)
[*]    {
[*]      strTemp &#43;= *it;
[*]      it&#43;&#43;;
[*]      if(it != m_RecipientList.end())
[*]                strTemp &#43;= &quot;,&quot;;
[*]    }
[*]    strTemp &#43;= &quot;\n&quot;;
[*]    m_MailContent.push_back(strTemp);
[*]    if(strSubject != &quot;&quot;)
[*]    {
[*]      strTemp = &quot;Subject: &quot;;
[*]      strTemp &#43;= strSubject;
[*]      strTemp &#43;= &quot;\n&quot;;
[*]      m_MailContent.push_back(strTemp);
[*]    }
[*]    m_MailContent.push_back(&quot;Content-Transfer-Encoding: 8bit\n&quot;);
[*]    m_MailContent.push_back(&quot;Content-Type: text/html; \n Charset=\&quot;UTF-8\&quot;\n\n&quot;);
[*]    if(strContent != &quot;&quot;)
[*]    {
[*]      m_MailContent.push_back(strContent);
[*]    }
[*]      
[*]    return true;
[*]}
[*]
[*]bool CSendMail::SendMail(const std::string& strSubject, const std::string& strMailBody)   
[*]{
[*]    m_MailContent.clear();
[*]    m_iMailContentPos = 0;
[*]    ConstructHead(strSubject, strMailBody);
[*]    bool bRet = true;
[*]    CURL *curl;
[*]    CURLM *mcurl;
[*]    int still_running = 1;
[*]    struct timeval mp_start;
[*]    char mp_timedout = 0;
[*]    struct curl_slist* rcpt_list = NULL;
[*]
[*]    curl_global_init(CURL_GLOBAL_DEFAULT);
[*]
[*]    curl = curl_easy_init();
[*]    if (!curl)
[*]    {
[*]      printf(&quot;Init curl failed!\n&quot;);
[*]      return false;
[*]    }
[*]
[*]    mcurl = curl_multi_init();
[*]    if (!mcurl)
[*]    {
[*]      printf(&quot;Init mcurl failed!\n&quot;);
[*]      return false;
[*]    }
[*]    for(std::list<std::string >::iterator it = m_RecipientList.begin(); it != m_RecipientList.end();it&#43;&#43;)
[*]    {
[*]      rcpt_list = curl_slist_append(rcpt_list, it->c_str());
[*]    }
[*]      
[*]    if(m_strSmtpServer == &quot;&quot; || m_iPort <= 0)
[*]    {
[*]      printf(&quot;smtp server couldn't be empty, or port must be large than 0!\n&quot;);
[*]         
[*]      curl_slist_free_all(rcpt_list);
[*]      curl_multi_cleanup(mcurl);
[*]      curl_easy_cleanup(curl);
[*]      curl_global_cleanup();
[*]      return false;
[*]    }
[*]    std::string strUrl = &quot;smtp://&quot; &#43; m_strSmtpServer;
[*]    strUrl &#43;= &quot;:&quot;;
[*]    char cPort;
[*]    memset(cPort, 0, 10);
[*]    sprintf(cPort, &quot;%d&quot;, m_iPort);
[*]    strUrl &#43;= cPort;
[*]    curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());
[*]      
[*]    if(m_strUser != &quot;&quot;)
[*]    {
[*]      curl_easy_setopt(curl, CURLOPT_USERNAME, m_strUser.c_str());
[*]    }
[*]    if(m_strPsw != &quot;&quot;)
[*]    {
[*]      curl_easy_setopt(curl, CURLOPT_PASSWORD, m_strPsw.c_str());
[*]    }
[*]      
[*]    curl_easy_setopt(curl, CURLOPT_READFUNCTION, &CSendMail::read_callback);
[*]      
[*]    if(m_strMailFrom == &quot;&quot;)
[*]    {
[*]      printf(&quot;Mail from address couldn't be empty!\n&quot;);
[*]         
[*]      curl_slist_free_all(rcpt_list);
[*]      curl_multi_cleanup(mcurl);
[*]      curl_easy_cleanup(curl);
[*]      curl_global_cleanup();
[*]      return false;
[*]    }
[*]    curl_easy_setopt(curl, CURLOPT_MAIL_FROM, m_strMailFrom.c_str());
[*]    curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, rcpt_list);
[*]    curl_easy_setopt(curl, CURLOPT_USE_SSL, (long) CURLUSESSL_ALL);
[*]    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
[*]    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
[*]    curl_easy_setopt(curl, CURLOPT_READDATA, this);
[*]    curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
[*]    curl_easy_setopt(curl, CURLOPT_SSLVERSION, 0L);
[*]    curl_easy_setopt(curl, CURLOPT_SSL_SESSIONID_CACHE, 0L);
[*]    curl_multi_add_handle(mcurl, curl);
[*]
[*]    mp_timedout = 0;
[*]    mp_start = tvnow();
[*]
[*]    /* we start some action by calling perform right away */
[*]    curl_multi_perform(mcurl, &still_running);
[*]
[*]    while (still_running) {
[*]      struct timeval timeout;
[*]      int rc; /* select() return code */
[*]
[*]      fd_set fdread;
[*]      fd_set fdwrite;
[*]      fd_set fdexcep;
[*]      int maxfd = -1;
[*]
[*]      long curl_timeo = -1;
[*]
[*]      FD_ZERO(&fdread);
[*]      FD_ZERO(&fdwrite);
[*]      FD_ZERO(&fdexcep);
[*]
[*]      /* set a suitable timeout to play around with */
[*]      timeout.tv_sec = 1;
[*]      timeout.tv_usec = 0;
[*]
[*]      curl_multi_timeout(mcurl, &curl_timeo);
[*]      if (curl_timeo >= 0) {
[*]            timeout.tv_sec = curl_timeo / 1000;
[*]            if (timeout.tv_sec > 1)
[*]                timeout.tv_sec = 1;
[*]            else
[*]                timeout.tv_usec = (curl_timeo % 1000) * 1000;
[*]      }
[*]
[*]      /* get file descriptors from the transfers */
[*]      curl_multi_fdset(mcurl, &fdread, &fdwrite, &fdexcep, &maxfd);
[*]
[*]      /* In a real-world program you OF COURSE check the return code of the
[*]         function calls.On success, the value of maxfd is guaranteed to be
[*]         greater or equal than -1.We call select(maxfd &#43; 1, ...), specially in
[*]         case of (maxfd == -1), we call select(0, ...), which is basically equal
[*]         to sleep. */
[*]
[*]      rc = select(maxfd &#43; 1, &fdread, &fdwrite, &fdexcep, &timeout);
[*]
[*]      if (tvdiff(tvnow(), mp_start) > MULTI_PERFORM_HANG_TIMEOUT) {
[*]            fprintf(stderr, &quot;ABORTING TEST, since it seems &quot;
[*]                  &quot;that it would have run forever.\n&quot;);
[*]            bRet = false;
[*]            break;
[*]      }
[*]
[*]      switch (rc) {
[*]            case -1:
[*]                /* select error */
[*]                printf(&quot;select error\n&quot;);
[*]                bRet = false;
[*]                break;
[*]            case 0: /* timeout */
[*]                printf(&quot;time out, retry again!\n&quot;);
[*]                curl_multi_perform(mcurl, &still_running);
[*]                break;
[*]            default: /* action */
[*]                curl_multi_perform(mcurl, &still_running);
[*]                break;
[*]      }
[*]    }
[*]
[*]    curl_multi_remove_handle(mcurl, curl);
[*]    curl_slist_free_all(rcpt_list);
[*]    curl_multi_cleanup(mcurl);
[*]    curl_easy_cleanup(curl);
[*]    curl_global_cleanup();
[*]    return bRet;
[*]}
[*]
[*]bool CSendMail::SendMail(const std::string & strSubject, const char* pMailBody, int len)
[*]{
[*]    std::string strMailContent;
[*]    strMailContent.append(pMailBody, len);
[*]      
[*]    return SendMail(strSubject, strMailContent);
[*]}
[*]
[*]bool CSendMail::SendMail(const std::string& strUser, const std::string& strPsw, const std::string& strSmtpServer, int iPort, std::list<std::string>& recipientList, const std::string& strMailFrom, const std::string& strSubject, const std::string& strMailBody)
[*]{
[*]    m_strUser = strUser;
[*]    m_strPsw = strPsw;
[*]    m_strSmtpServer = strSmtpServer;
[*]    m_iPort = iPort;
[*]    std::copy(recipientList.begin(), recipientList.end(), m_RecipientList.begin());
[*]    m_strMailFrom = strMailFrom;
[*]      
[*]    return SendMail(strSubject, strMailBody);
[*]      
[*]}
[*]
[*]bool CSendMail::SendMail(const std::string& strUser, const std::string& strPsw, const std::string& strSmtpServer, int iPort, std::list<std::string>& recipientList, const std::string& strMailFrom, const std::string& strSubject, const char* pMailBody, int len)
[*]{
[*]    std::string strMailContent;
[*]    strMailContent.append(pMailBody, len);
[*]    return SendMail(strUser, strPsw, strSmtpServer, iPort, recipientList, strMailFrom, strSubject, strMailContent);
[*]}
[*]
[*]bool CSendMail::SendMail(const std::string& strUser, const std::string& strPsw, const std::string& strSmtpServer, int iPort, const std::string& strMailTo, const std::string& strMailFrom, const std::string& strSubject, const std::string& strMailBody)
[*]{
[*]    std::list<std::string> recipientList;
[*]    recipientList.push_back(strMailTo);
[*]      
[*]    return SendMail(strUser, strPsw, strSmtpServer, iPort, recipientList, strMailFrom, strSubject, strMailBody);
[*]}
[*]
[*]bool CSendMail::SendMail(const std::string& strUser, const std::string& strPsw, const std::string& strSmtpServer, int iPort, const std::string& strMailTo, const std::string& strMailFrom, const std::string& strSubject, const char* pMailBody, int len)
[*]{
[*]    std::string strMailContent;
[*]    strMailContent.append(pMailBody, len);
[*]    return SendMail(strUser, strPsw, strSmtpServer, iPort, strMailTo, strMailFrom, strSubject, strMailContent);
[*]
[*]}

这个是通过libcurl multi接口来做的,所以使用的时候记得要libcurl库的支持。
页: [1]
查看完整版本: libcurl sendmail