libcurl发送邮件C++类

先上源码

H

/* 
 * 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

/* 
 * File:   CSendMail.cpp
 * Author: root
 * 
 * Created on January 16, 2012, 6:14 PM
 */

#include "CSendMail.h"

CSendMail::CSendMail() 
{
    m_strUser = "";
    m_strPsw = "";
    m_strSmtpServer = "";
    m_iPort = -1;
    m_RecipientList.clear();
    m_strMailFrom = "";
    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[pSm->m_iMailContentPos].length();

        memcpy(ptr, pSm->m_MailContent[pSm->m_iMailContentPos].c_str(), pSm->m_MailContent[pSm->m_iMailContentPos].length());
        pSm->m_iMailContentPos++; /* 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+
        (newer.tv_usec-older.tv_usec)/1000;
}

bool CSendMail::ConstructHead(const std::string & strSubject, const std::string & strContent)
{
    m_MailContent.push_back("MIME-Versioin: 1.0\n");
    std::string strTemp = "To: ";
    for(std::list<std::string >::iterator it = m_RecipientList.begin(); it != m_RecipientList.end();)
    {
        strTemp += *it;
        it++;
        if(it != m_RecipientList.end())
                strTemp += ",";
    }
    strTemp += "\n";
    m_MailContent.push_back(strTemp);
    if(strSubject != "")
    {
        strTemp = "Subject: ";
        strTemp += strSubject;
        strTemp += "\n";
        m_MailContent.push_back(strTemp);
    }
    m_MailContent.push_back("Content-Transfer-Encoding: 8bit\n");
    m_MailContent.push_back("Content-Type: text/html; \n Charset=\"UTF-8\"\n\n");
    if(strContent != "")
    {
        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("Init curl failed!\n");
        return false;
    }

    mcurl = curl_multi_init();
    if (!mcurl)
    {
        printf("Init mcurl failed!\n");
        return false;
    }
    for(std::list<std::string >::iterator it = m_RecipientList.begin(); it != m_RecipientList.end();it++)
    {
        rcpt_list = curl_slist_append(rcpt_list, it->c_str());
    }
    
    if(m_strSmtpServer == "" || m_iPort <= 0)
    {
        printf("smtp server couldn't be empty, or port must be large than 0!\n");
        
        curl_slist_free_all(rcpt_list);
        curl_multi_cleanup(mcurl);
        curl_easy_cleanup(curl);
        curl_global_cleanup();
        return false;
    }
    std::string strUrl = "smtp://" + m_strSmtpServer;
    strUrl += ":";
    char cPort[10];
    memset(cPort, 0, 10);
    sprintf(cPort, "%d", m_iPort);
    strUrl += cPort;
    curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());
    
    if(m_strUser != "")
    {
        curl_easy_setopt(curl, CURLOPT_USERNAME, m_strUser.c_str());
    }
    if(m_strPsw != "")
    {
        curl_easy_setopt(curl, CURLOPT_PASSWORD, m_strPsw.c_str());
    }
    
    curl_easy_setopt(curl, CURLOPT_READFUNCTION, &CSendMail::read_callback);
    
    if(m_strMailFrom == "")
    {
        printf("Mail from address couldn't be empty!\n");
        
        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 + 1, ...), specially in
           case of (maxfd == -1), we call select(0, ...), which is basically equal
           to sleep. */

        rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout);

        if (tvdiff(tvnow(), mp_start) > MULTI_PERFORM_HANG_TIMEOUT) {
            fprintf(stderr, "ABORTING TEST, since it seems "
                    "that it would have run forever.\n");
            bRet = false;
            break;
        }

        switch (rc) {
            case -1:
                /* select error */
                printf("select error\n");
                bRet = false;
                break;
            case 0: /* timeout */
                printf("time out, retry again!\n");
                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库的支持。


调用代码示例

/* 
 * File:   main.cpp
 * Author:jaylong35
 *
 * Created on January 16, 2012, 6:14 PM
 */

#include <cstdlib>
#include <iostream>
#include "CSendMail.h"

using namespace std;

#define USERNAME "xx@126.com"
#define PASSWORD "xxxxxx"
#define SMTPSERVER "smtp.126.com"
#define SMTPPORT ":25" 
#define RECIPIENT "<kkk@126.com>"
#define MAILFROM "<xx@126.com>"

int main(int argc, char** argv)
{
  
    CSendMail sendMail(USERNAME, PASSWORD, SMTPSERVER, 25, MAILFROM);    
    sendMail.AddRecipient(RECIPIENT);
    sendMail.SendMail("mytestfirst","I hate you");
    return 0; 
}
 






评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值