使用libcurl库实现SMTP发送邮件

http://blog.csdn.net/chenlycly/article/details/71057259

1、本文给出封装的C++类,头文件如下:

[cpp] view plain copy
  1. #pragma once    
  2.   
  3. #include     
  4. #include     
  5.   
  6. #define SKIP_PEER_VERIFICATION    
  7. #define SKIP_HOSTNAME_VERIFICATION    
  8.   
  9.   
  10. class CSmtpSendMail{    
  11. public:    
  12.     CSmtpSendMail(const std::string & charset="gb2312"); // 也可以传入utf  
  13.   
  14.     //设置stmp服务器、用户名、密码、端口(端口其实不用指定,libcurl默认25,但如果是smtps则默认是465)    
  15.     void SetSmtpServer(const std::string &username, const std::string& password, const std::string& servername, const std::string &port="25");    
  16.     //发送者姓名,可以不用    
  17.   
  18.     void SetSendName(const std::string& sendname);    
  19.   
  20.     //发送者邮箱     
  21.     void SetSendMail(const std::string& sendmail);    
  22.   
  23.     //添加收件人    
  24.     void AddRecvMail(const std::string& recvmail);  
  25.   
  26.     //设置主题    
  27.     void SetSubject(const std::string &subject);    
  28.   
  29.     //设置正文内容    
  30.     void SetBodyContent(const std::string &content);    
  31.   
  32.     //添加附件    
  33.     void AddAttachment(const std::string &filename);    
  34.   
  35.     //发送邮件    
  36.     bool SendMail();    
  37. private:    
  38.   
  39.     //回调函数,将MIME协议的拼接的字符串由libcurl发出    
  40.     static size_t payload_source(void *ptr, size_t size, size_t nmemb, void *stream);    
  41.   
  42.     //创建邮件MIME内容    
  43.     void CreatMessage();    
  44.   
  45.     //获取文件类型    
  46.     int GetFileType(std::string const& stype);    
  47.   
  48.     //设置文件名    
  49.     void SetFileName(const std::string& FileName);    
  50.   
  51.     //设置文件的contenttype    
  52.     void SetContentType(std::string const& stype);    
  53.   
  54.     //得到文件名    
  55.     void GetFileName(const std::string& file, std::string& filename);   
  56.   
  57.     //得到文件类型    
  58.     void GetFileType(const std::string& file, std::string& stype);    
  59.   
  60. private:    
  61.     std::string m_strCharset; //邮件编码    
  62.     std::string m_strSubject; //邮件主题    
  63.     std::string m_strContent; //邮件内容    
  64.     std::string m_strFileName; //文件名    
  65.     std::string m_strMessage;// 整个MIME协议字符串    
  66.     std::string m_strUserName;//用户名    
  67.     std::string m_strPassword;//密码    
  68.     std::string m_strServerName;//smtp服务器    
  69.     std::string m_strPort;//端口    
  70.     std::string m_strSendName;//发送者姓名    
  71.     std::string m_strSendMail;//发送者邮箱    
  72.     std::string m_strContentType;//附件contenttype    
  73.     std::string m_strFileContent;//附件内容    
  74.   
  75.     std::vector m_vRecvMail; //收件人容器    
  76.     std::vector m_vAttachMent;//附件容器    
  77. };    

cpp文件实现如下:

[cpp] view plain copy
  1. #include "stdafx.h"      
  2. #include "smtp.h"    
  3. #include "base64.h"    
  4. #include ".\curl\curl.h"   
  5. #include     
  6. #include     
  7. #include     
  8.   
  9. CSmtpSendMail::CSmtpSendMail(const std::string & charset)    
  10. {    
  11.     m_strCharset = charset;    
  12.     m_vRecvMail.clear();    
  13. }    
  14.   
  15. void CSmtpSendMail::SetSmtpServer(const std::string & username, const std::string &password, const std::string & servername, const std::string & port)    
  16. {    
  17.     m_strUserName = username;    
  18.     m_strPassword = password;    
  19.     m_strServerName = servername;    
  20.     m_strPort = port;    
  21. }    
  22.   
  23. void CSmtpSendMail::SetSendName(const std::string & sendname)    
  24. {    
  25.     std::string strTemp = "";    
  26.     strTemp += "=?";    
  27.     strTemp += m_strCharset;    
  28.     strTemp += "?B?";    
  29.     strTemp += base64_encode((unsigned char *)sendname.c_str(), sendname.size());    
  30.     strTemp += "?=";    
  31.     m_strSendName = strTemp;    
  32. }    
  33.   
  34. void CSmtpSendMail::SetSendMail(const std::string & sendmail)    
  35. {    
  36.     m_strSendMail = sendmail;    
  37. }    
  38.   
  39. void CSmtpSendMail::AddRecvMail(const std::string & recvmail)    
  40. {    
  41.     m_vRecvMail.push_back(recvmail);    
  42. }    
  43.   
  44. void CSmtpSendMail::SetSubject(const std::string & subject)    
  45. {    
  46.     std::string strTemp = "";    
  47.     strTemp = "Subject: ";    
  48.     strTemp += "=?";    
  49.     strTemp += m_strCharset;    
  50.     strTemp += "?B?";    
  51.     strTemp += base64_encode((unsigned char *)subject.c_str(), subject.size());    
  52.     strTemp += "?=";    
  53.     m_strSubject = strTemp;    
  54. }    
  55.   
  56. void CSmtpSendMail::SetBodyContent(const std::string & content)    
  57. {    
  58.     m_strContent = content;    
  59. }    
  60.   
  61. void CSmtpSendMail::AddAttachment(const std::string & filename)    
  62. {    
  63.     m_vAttachMent.push_back(filename);    
  64. }    
  65.   
  66. bool CSmtpSendMail::SendMail()    
  67. {    
  68.     CreatMessage();    
  69.     bool ret = true;    
  70.     CURL *curl;    
  71.     CURLcode res = CURLE_OK;    
  72.     struct curl_slist *recipients = NULL;    
  73.   
  74.     curl = curl_easy_init();    
  75.     if (curl) {    
  76.         /* Set username and password */                                          
  77.         curl_easy_setopt(curl, CURLOPT_USERNAME, m_strUserName.c_str());    
  78.         curl_easy_setopt(curl, CURLOPT_PASSWORD, m_strPassword.c_str());    
  79.         std::string tmp = "smtp://";    
  80.         tmp += m_strServerName;    
  81.         // 注意不能直接传入tmp,应该带上.c_str(),否则会导致下面的  
  82.         // curl_easy_perform调用返回CURLE_COULDNT_RESOLVE_HOST错误  
  83.         // 码  
  84.         curl_easy_setopt(curl, CURLOPT_URL, tmp.c_str());    
  85.         /* If you want to connect to a site who isn't using a certificate that is  
  86.         * signed by one of the certs in the CA bundle you have, you can skip the  
  87.         * verification of the server's certificate. This makes the connection  
  88.         * A LOT LESS SECURE.  
  89.         *  
  90.         * If you have a CA cert for the server stored someplace else than in the  
  91.         * default bundle, then the CURLOPT_CAPATH option might come handy for  
  92.         * you. */    
  93. #ifdef SKIP_PEER_VERIFICATION    
  94.         curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);    
  95. #endif    
  96.   
  97.         /* If the site you're connecting to uses a different host name that what  
  98.         * they have mentioned in their server certificate's commonName (or  
  99.         * subjectAltName) fields, libcurl will refuse to connect. You can skip  
  100.         * this check, but this will make the connection less secure. */    
  101. #ifdef SKIP_HOSTNAME_VERIFICATION    
  102.         curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);    
  103. #endif    
  104.   
  105.         /* Note that this option isn't strictly required, omitting it will result  
  106.         * in libcurl sending the MAIL FROM command with empty sender data. All  
  107.         * autoresponses should have an empty reverse-path, and should be directed  
  108.         * to the address in the reverse-path which triggered them. Otherwise,  
  109.         * they could cause an endless loop. See RFC 5321 Section 4.5.5 for more  
  110.         * details.  
  111.         */    
  112.         //curl_easy_setopt(curl, CURLOPT_MAIL_FROM, FROM);     
  113.         curl_easy_setopt(curl, CURLOPT_MAIL_FROM, m_strSendMail.c_str());    
  114.         /* Add two recipients, in this particular case they correspond to the  
  115.         * To: and Cc: addressees in the header, but they could be any kind of  
  116.         * recipient. */    
  117.         for (size_t i = 0; i < m_vRecvMail.size(); i++) {    
  118.   
  119.             recipients = curl_slist_append(recipients, m_vRecvMail[i].c_str());    
  120.         }    
  121.         curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients);    
  122.   
  123.         std::stringstream stream;    
  124.         stream.str(m_strMessage.c_str());    
  125.         stream.flush();    
  126.         /* We're using a callback function to specify the payload (the headers and  
  127.         * body of the message). You could just use the CURLOPT_READDATA option to  
  128.         * specify a FILE pointer to read from. */    
  129.   
  130.         // 注意回调函数必须设置为static  
  131.         curl_easy_setopt(curl, CURLOPT_READFUNCTION, &CSmtpSendMail::payload_source);    
  132.         curl_easy_setopt(curl, CURLOPT_READDATA, (void *)&stream);    
  133.         curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);    
  134.   
  135.         /* Since the traffic will be encrypted, it is very useful to turn on debug  
  136.         * information within libcurl to see what is happening during the  
  137.         * transfer */    
  138.         curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);    
  139.   
  140.         int nTimes = 0;  
  141.         /* Send the message */    
  142.         res = curl_easy_perform(curl);    
  143.         CURLINFO info = CURLINFO_NONE;    
  144.         curl_easy_getinfo(curl, info);    
  145.         /* Check for errors */    
  146.   
  147.         while (res != CURLE_OK) {    
  148.   
  149.             nTimes++;  
  150.             if ( nTimes > 5 )  
  151.             {  
  152.                 break;  
  153.             }  
  154.             fprintf(stderr, "curl_easy_perform() failed: %s\n\n",    
  155.                 curl_easy_strerror(res));    
  156.   
  157.             char achTip[512] = {0};  
  158.             sprintf( achTip, "curl_easy_perform() failed: %s\n\n", curl_easy_strerror(res) );  
  159.             ::MessageBoxA( NULL, achTip, "Tip", MB_OK);  
  160.             ret = false;    
  161.   
  162.             /*              Sleep( 100 ); 
  163.             res = curl_easy_perform(curl); */   
  164.         }    
  165.   
  166.         /* Free the list of recipients */    
  167.         curl_slist_free_all(recipients);    
  168.   
  169.         /* Always cleanup */    
  170.         curl_easy_cleanup(curl);    
  171.   
  172.     }    
  173.     return ret;    
  174. }    
  175.   
  176. size_t CSmtpSendMail::payload_source(void *ptr, size_t size, size_t nmemb, void *stream)    
  177. {    
  178.     size_t num_bytes = size * nmemb;    
  179.     char* data = (char*)ptr;    
  180.     std::stringstream* strstream = (std::stringstream*)stream;    
  181.   
  182.     strstream->read(data, num_bytes);    
  183.   
  184.     return strstream->gcount();    
  185. }    
  186.   
  187. void CSmtpSendMail::CreatMessage()    
  188. {    
  189.     m_strMessage = "From: ";    
  190.     m_strMessage += m_strSendMail;    
  191.     m_strMessage += "\r\nReply-To: ";    
  192.     m_strMessage += m_strSendMail;    
  193.     m_strMessage += "\r\nTo: ";    
  194.     for (size_t i = 0; i < m_vRecvMail.size(); i++)    
  195.     {    
  196.         if (i > 0) {    
  197.             m_strMessage += ",";    
  198.         }    
  199.         m_strMessage += m_vRecvMail[i];    
  200.     }    
  201.     m_strMessage += "\r\n";    
  202.     m_strMessage += m_strSubject;    
  203.     m_strMessage += "\r\nX-Mailer: The Bat! (v3.02) Professional";    
  204.     m_strMessage += "\r\nMime-Version: 1.0";    
  205.     m_strMessage += "\r\nContent-Type: multipart/mixed;";    
  206.     m_strMessage += "boundary=\"simple boundary\"";    
  207.     m_strMessage += "\r\nThis is a multi-part message in MIME format.";    
  208.     m_strMessage += "\r\n--simple boundary";    
  209.     //正文    
  210.     m_strMessage += "\r\nContent-Type: text/html;";    
  211.     m_strMessage += "charset=";    
  212.     m_strMessage += "\"";    
  213.     m_strMessage += m_strCharset;    
  214.     m_strMessage += "\"";    
  215.     m_strMessage += "\r\nContent-Transfer-Encoding: 7BIT";    
  216.     m_strMessage += "\r\n\r\n";    
  217.     m_strMessage += m_strContent;    
  218.   
  219.     //附件    
  220.     std::string filename = "";    
  221.     std::string filetype = "";    
  222.     for (size_t i = 0; i < m_vAttachMent.size(); i++)    
  223.     {    
  224.         m_strMessage += "\r\n--simple boundary";    
  225.         GetFileName(m_vAttachMent[i], filename);    
  226.         GetFileType(m_vAttachMent[i], filetype);    
  227.         SetContentType(filetype);    
  228.         SetFileName(filename);    
  229.   
  230.         m_strMessage += "\r\nContent-Type: ";    
  231.         m_strMessage += m_strContentType;    
  232.         m_strMessage += "\tname=";    
  233.         m_strMessage += "\"";    
  234.         m_strMessage += m_strFileName;    
  235.         m_strMessage += "\"";    
  236.         m_strMessage += "\r\nContent-Disposition:attachment;filename=";    
  237.         m_strMessage += "\"";    
  238.         m_strMessage += m_strFileName;    
  239.         m_strMessage += "\"";    
  240.         m_strMessage += "\r\nContent-Transfer-Encoding:base64";     
  241.         m_strMessage += "\r\n\r\n";    
  242.   
  243.   
  244.         FILE *pt = NULL;    
  245.         if ((pt = fopen(m_vAttachMent[i].c_str(), "rb")) == NULL) {    
  246.   
  247.             std::cerr << "打开文件失败: " << m_vAttachMent[i] <
  248.             continue;    
  249.         }    
  250.         fseek(pt, 0, SEEK_END);    
  251.         int len = ftell(pt);    
  252.         fseek(pt, 0, SEEK_SET);    
  253.         int rlen = 0;    
  254.         char buf[55];    
  255.         for (size_t i = 0; i < len / 54 + 1; i++)    
  256.         {    
  257.             memset(buf, 0, 55);    
  258.             rlen = fread(buf, sizeof(char), 54, pt);    
  259.             m_strMessage += base64_encode((const unsigned char*)buf, rlen);    
  260.             m_strMessage += "\r\n";    
  261.         }    
  262.         fclose(pt);    
  263.         pt = NULL;    
  264.   
  265.     }    
  266.     m_strMessage += "\r\n--simple boundary--\r\n";    
  267.   
  268. }    
  269.   
  270.   
  271. int CSmtpSendMail::GetFileType(std::string const & stype)    
  272. {    
  273.     if (stype == "txt")    
  274.     {    
  275.         return 0;    
  276.     }    
  277.     else if (stype == "xml")    
  278.     {    
  279.         return 1;    
  280.     }    
  281.     else if (stype == "html")    
  282.     {    
  283.         return 2;    
  284.     }    
  285.     else if (stype == "jpeg")    
  286.     {    
  287.         return 3;    
  288.     }    
  289.     else if (stype == "png")    
  290.     {    
  291.         return 4;    
  292.     }    
  293.     else if (stype == "gif")    
  294.     {    
  295.         return 5;    
  296.     }    
  297.     else if (stype == "exe")    
  298.     {    
  299.         return 6;    
  300.     }    
  301.   
  302.     return -1;    
  303. }    
  304.   
  305. void CSmtpSendMail::SetFileName(const std::string & FileName)    
  306. {    
  307.     std::string EncodedFileName = "=?";    
  308.     EncodedFileName += m_strCharset;    
  309.     EncodedFileName += "?B?";//修改    
  310.     EncodedFileName += base64_encode((unsigned char *)FileName.c_str(), FileName.size());    
  311.     EncodedFileName += "?=";    
  312.     m_strFileName = EncodedFileName;    
  313. }    
  314.   
  315. void CSmtpSendMail::SetContentType(std::string const & stype)    
  316. {    
  317.     int type = GetFileType(stype);    
  318.     switch (type)    
  319.     {//    
  320.     case 0:    
  321.         m_strContentType = "plain/text;";    
  322.         break;    
  323.   
  324.     case 1:    
  325.         m_strContentType = "text/xml;";    
  326.         break;    
  327.   
  328.     case 2:    
  329.         m_strContentType = "text/html;";    
  330.   
  331.     case 3:    
  332.         m_strContentType = "image/jpeg;";    
  333.         break;    
  334.   
  335.     case 4:    
  336.         m_strContentType = "image/png;";    
  337.         break;    
  338.   
  339.     case 5:    
  340.         m_strContentType = "image/gif;";    
  341.         break;    
  342.   
  343.     case 6:    
  344.         m_strContentType = "application/x-msdownload;";    
  345.         break;    
  346.   
  347.     default:    
  348.         m_strContentType = "application/octet-stream;";    
  349.         break;    
  350.     }    
  351. }    
  352.   
  353. void CSmtpSendMail::GetFileName(const std::string& file, std::string& filename)    
  354. {    
  355.   
  356.     std::string::size_type p = file.find_last_of('/');    
  357.     if (p == std::string::npos)    
  358.         p = file.find_last_of('\\');    
  359.     if (p != std::string::npos) {    
  360.         p += 1; // get past folder delimeter    
  361.         filename = file.substr(p, file.length() - p);    
  362.     }    
  363. }    
  364.   
  365. void CSmtpSendMail::GetFileType(const std::string & file, std::string & stype)    
  366. {    
  367.     std::string::size_type p = file.find_last_of('.');    
  368.     if (p != std::string::npos) {    
  369.         p += 1; // get past folder delimeter    
  370.         stype = file.substr(p, file.length() - p);    
  371.     }    
  372. }    

2、上面使用到的base64编码的头文件和cpp文件如下:

[cpp] view plain copy
  1. #ifndef _BASE64_H_    
  2. #define _BASE64_H_    
  3.   
  4. #include   
  5.   
  6. std::string base64_encode(unsigned char const* , unsigned int len);    
  7. std::string base64_decode(std::string const& s);    
  8.   
  9. #endif  

[cpp] view plain copy
  1. /*    
  2.    base64.cpp and base64.h   
  3.    
  4.    Copyright (C) 2004-2008 Ren?Nyffenegger   
  5.    
  6.    This source code is provided 'as-is', without any express or implied   
  7.    warranty. In no event will the author be held liable for any damages   
  8.    arising from the use of this software.   
  9.    
  10.    Permission is granted to anyone to use this software for any purpose,   
  11.    including commercial applications, and to alter it and redistribute it   
  12.    freely, subject to the following restrictions:   
  13.    
  14.    1. The origin of this source code must not be misrepresented; you must not   
  15.       claim that you wrote the original source code. If you use this source code   
  16.       in a product, an acknowledgment in the product documentation would be   
  17.       appreciated but is not required.   
  18.    
  19.    2. Altered source versions must be plainly marked as such, and must not be   
  20.       misrepresented as being the original source code.   
  21.    
  22.    3. This notice may not be removed or altered from any source distribution.   
  23.    
  24.    Ren?Nyffenegger [email protected]   
  25.    
  26. */    
  27. #include "stdafx.h"  
  28. #include "base64.h"    
  29. #include     
  30.     
  31. static const std::string base64_chars =     
  32.              "ABCDEFGHIJKLMNOPQRSTUVWXYZ"    
  33.              "abcdefghijklmnopqrstuvwxyz"    
  34.              "0123456789+/";    
  35.     
  36.     
  37. static inline bool is_base64(unsigned char c)     
  38. {    
  39.   return (isalnum(c) || (c == '+') || (c == '/'));    
  40. }    
  41.     
  42. std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len)     
  43. {    
  44.   std::string ret;    
  45.   int i = 0, j = 0;    
  46.   unsigned char char_array_3[3], char_array_4[4];    
  47.     
  48.   while (in_len--)    
  49.     {    
  50.     char_array_3[i++] = *(bytes_to_encode++);    
  51.     if (i == 3)     
  52.         {    
  53.       char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;    
  54.       char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);    
  55.       char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);    
  56.       char_array_4[3] = char_array_3[2] & 0x3f;    
  57.     
  58.       for(i = 0; (i <4) ; i++)    
  59.         ret += base64_chars[char_array_4[i]];    
  60.       i = 0;    
  61.     }    
  62.   }    
  63.     
  64.   if (i)    
  65.   {    
  66.     for(j = i; j < 3; j++)    
  67.       char_array_3[j] = '\0';    
  68.     
  69.     char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;    
  70.     char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);    
  71.     char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);    
  72.     char_array_4[3] = char_array_3[2] & 0x3f;    
  73.     
  74.     for (j = 0; (j < i + 1); j++)    
  75.       ret += base64_chars[char_array_4[j]];    
  76.     
  77.     while((i++ < 3))    
  78.       ret += '=';    
  79.     
  80.   }    
  81.     
  82.   return ret;    
  83.     
  84. }    
  85.     
  86. std::string base64_decode(std::string const& encoded_string)     
  87. {    
  88.   int in_len = encoded_string.size();    
  89.   int i = 0, j = 0, in_ = 0;    
  90.   unsigned char char_array_4[4], char_array_3[3];    
  91.   std::string ret;    
  92.     
  93.   while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_]))     
  94.     {    
  95.     char_array_4[i++] = encoded_string[in_]; in_++;    
  96.     if (i ==4) {    
  97.       for (i = 0; i <4; i++)    
  98.         char_array_4[i] = base64_chars.find(char_array_4[i]);    
  99.     
  100.       char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);    
  101.       char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);    
  102.       char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];    
  103.     
  104.       for (i = 0; (i < 3); i++)    
  105.         ret += char_array_3[i];    
  106.       i = 0;    
  107.     }    
  108.   }    
  109.     
  110.   if (i)     
  111.     {    
  112.     for (j = i; j <4; j++)    
  113.       char_array_4[j] = 0;    
  114.     
  115.     for (j = 0; j <4; j++)    
  116.       char_array_4[j] = base64_chars.find(char_array_4[j]);    
  117.     
  118.     char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);    
  119.     char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);    
  120.     char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];    
  121.     
  122.     for (j = 0; (j < i - 1); j++)     
  123.             ret += char_array_3[j];    
  124.   }    
  125.     
  126.   return ret;    
  127. }    

3、测试代码如下:
[cpp] view plain copy
  1. #include     
  2. #include     
  3. #include "CSendMail.h"    
  4.     
  5. using namespace std;    
  6.     
  7. #define USERNAME "[email protected]"    
  8. #define PASSWORD "xxxxxx"    
  9. #define SMTPSERVER "smtp.suhu.com"    
  10. #define SMTPPORT ":25"     
  11. #define RECIPIENT ""    
  12. #define MAILFROM ""    
  13.     
  14. int main(int argc, char** argv)    
  15. {    
  16.       
  17.     CSendMail sendMail( USERNAME, PASSWORD, SMTPSERVER, 25 );        
  18.    sendMail.SetSendName( MAILFROM );  
  19.    sendMail.SetSendMail( MAILFROM );  
  20.    sendMail.AddRecvMail( RECIPIENT );  
  21.    sendMail.SetSubject( "mail send test" );  
  22.    sendMail.SetBodyContent( "this is a test!" );  
  23.     return 0;     
  24. }    

4、编译libcurl库

到libcurl官方网站上下载最新的libcurl代码zip包,具体编译过程参见:http://blog.csdn.net/chenlycly/article/details/71056875


参考: libcurl发送邮件C++类 : http://blog.csdn.net/jaylong35/article/details/7210291
libcurl实现smtp发送支持附件: http://blog.csdn.net/abqchina/article/details/53405269


你可能感兴趣的:(smtp协议)