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 "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.length();
[*]
[*] memcpy(ptr, pSm->m_MailContent.c_str(), pSm->m_MailContent.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;
[*] 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库的支持。
页:
[1]