基於jwSMTP的C++傳送Email的Demo
由於業務上存在傳送報警郵件的需求,一直想找一個簡單易用的傳送Email的C++庫。
終於找到了,它就是jwSTMP(http://sourceforge.net/projects/jwsmtp/)。
最新的jwSTMP版本(1.32.15)能夠跨平臺(BSD、Linux和Windows等)的支援以C++程式碼或者C++庫的形式編碼傳送Email。它可以傳送附件、支援多個收件人(最多100個),支援CC(抄送)和BCC(隱藏性抄送);同樣的,它也支援以HTML的方式傳送郵件。
我們知道傳送Email有POP3和SMTP兩種方式。目前jwSTMP不支援POP3的方式。但是它提供了MX lookup方式,即直接得到目的地址的郵件交換伺服器地址(MX)將郵件傳送出去。
現在說說如何使用吧。
下載和編譯。請到sourceforge上將它下載下來。如果使用Windows平臺,直接點選工程檔案即可(預設是VC6的工程檔案,我使用VS2008將工程檔案轉化也是可以的)然後編譯即可;如果使用Linux,請執行通行的三部曲:
./configure
make
make install
程式碼修改。適合中國人的習慣,我將使用163的郵箱服務展示jwSMTP的用法。
最簡單的demo1.cpp檔案如下:
- #include <iostream>
- // 由於標頭檔案所處的位置是jwsmtp-1.32.15\jwsmtp\jwsmtp,所以,需要注意include的路徑
- #include "jwsmtp/jwsmtp.h"
- int main(int argc, char* argv[])
- {
- jwsmtp::mailer m("testjwstmp@163.com"/*接收者*/, "testjwstmp@163.com"/*傳送者*/, "這裡填寫郵件標題",
- "這裡填寫郵件內容", "smtp.163.com",
- jwsmtp::mailer::SMTP_PORT, false);
- //經過測試,163支援的auth認證是PLAIN模式
- m.authtype(jwsmtp::mailer::PLAIN);
- //這裡輸入認證使用者名稱,注意哦,需要是***@163.com的使用者名稱
- m.username("testjwstmp@163.com");
- //這裡輸入密碼
- m.password("******");
- m.send(); // 這裡傳送郵件,需要注意的是,這裡是同步模式哦!
- std ::cout << m.response() << std::endl;//這裡返回是否成功,250代表傳送郵件成功;
- system("pause");
- return 0;
- }
需要注意的是,雖然我在測試時傳送在cpp檔案中寫入中文使用163.com傳送是沒有出現亂碼的,但是,在公司中傳送報警郵件則會出現亂碼。為了解決亂碼問題,需要使用網路上有人提供的string s2utfs(const string& strSrc)函式進行轉碼為utf8。
- #ifndef __CHARSET_CVT__
- #define __CHARSET_CVT__
- #include <string>
- #include <clocale>
- std::string ws2s(const std::wstring& ws)
- {
- std::string curLocale = setlocale(LC_ALL, NULL); // curLocale = "C";
- setlocale(LC_ALL, "chs");
- const wchar_t* _Source = ws.c_str();
- size_t _Dsize = 2 * ws.size() + 1;
- char *_Dest = new char[_Dsize];
- memset(_Dest, 0, _Dsize);
- wcstombs(_Dest, _Source, _Dsize);
- std::string result = _Dest;
- delete [] _Dest;
- setlocale(LC_ALL, curLocale.c_str());
- return result;
- }
- std::wstring s2ws(const std::string& s)
- {
- setlocale(LC_ALL, "chs");
- const char* _Source = s.c_str();
- size_t _Dsize = s.size() + 1;
- wchar_t* _Dest = new wchar_t[_Dsize];
- wmemset(_Dest, 0, _Dsize);
- int nret = mbstowcs(_Dest, _Source, _Dsize);
- std::wstring result = _Dest;
- delete [] _Dest;
- setlocale(LC_ALL, "C");
- return result;
- }
- std::wstring UTF2Uni(const char* src, std::wstring &t)
- {
- if (src == NULL)
- {
- return L"";
- }
- int size_s = strlen(src);
- int size_d = size_s + 10;
- wchar_t *des = new wchar_t[size_d];
- memset(des, 0, size_d * sizeof(wchar_t));
- int s = 0, d = 0;
- bool toomuchbyte = true; //set true to skip error prefix.
- while (s < size_s && d < size_d)
- {
- unsigned char c = src[s];
- if ((c & 0x80) == 0)
- {
- des[d++] += src[s++];
- }
- else if((c & 0xE0) == 0xC0) /// < 110x-xxxx 10xx-xxxx
- {
- WCHAR &wideChar = des[d++];
- wideChar = (src[s + 0] & 0x3F)<<6;
- wideChar |= (src[s + 1] & 0x3F);
- s += 2;
- }
- else if((c & 0xF0) == 0xE0) /// < 1110-xxxx 10xx-xxxx 10xx-xxxx
- {
- WCHAR &wideChar = des[d++];
- wideChar = (src[s + 0] & 0x1F)<<12;
- wideChar |= (src[s + 1] & 0x3F)<<6;
- wideChar |= (src[s + 2] & 0x3F);
- s += 3;
- }
- else if((c & 0xF8) == 0xF0) /// < 1111-0xxx 10xx-xxxx 10xx-xxxx 10xx-xxxx
- {
- WCHAR &wideChar = des[d++];
- wideChar = (src[s + 0] & 0x0F)<<18;
- wideChar = (src[s + 1] & 0x3F)<<12;
- wideChar |= (src[s + 2] & 0x3F)<<6;
- wideChar |= (src[s + 3] & 0x3F);
- s += 4;
- }
- else
- {
- WCHAR &wideChar = des[d++]; /// < 1111-10xx 10xx-xxxx 10xx-xxxx 10xx-xxxx 10xx-xxxx
- wideChar = (src[s + 0] & 0x07)<<24;
- wideChar = (src[s + 1] & 0x3F)<<18;
- wideChar = (src[s + 2] & 0x3F)<<12;
- wideChar |= (src[s + 3] & 0x3F)<<6;
- wideChar |= (src[s + 4] & 0x3F);
- s += 5;
- }
- }
- t = des;
- delete[] des;
- des = NULL;
- return t;
- }
- int Uni2UTF(const std::wstring& strRes, char *utf8, int nMaxSize)
- {
- if (utf8 == NULL)
- {
- return -1;
- }
- int len = 0;
- int size_d = nMaxSize;
- for (std::wstring::const_iterator it = strRes.begin(); it != strRes.end(); ++it)
- {
- wchar_t wchar = *it;
- if (wchar < 0x80)
- {
- //length = 1;
- utf8[len++] = (char)wchar;
- }
- else if(wchar < 0x800)
- {
- //length = 2;
- if (len + 1 >= size_d)
- {
- return -1;
- }
- utf8[len++] = 0xc0 | ( wchar >> 6 );
- utf8[len++] = 0x80 | ( wchar & 0x3f );
- }
- else if(wchar < 0x10000)
- {
- //length = 3;
- if (len + 2 >= size_d)
- {
- return -1;
- }
- utf8[len++] = 0xe0 | ( wchar >> 12 );
- utf8[len++] = 0x80 | ( (wchar >> 6) & 0x3f );
- utf8[len++] = 0x80 | ( wchar & 0x3f );
- }
- else if( wchar < 0x200000)
- {
- //length = 4;
- if (len + 3 >= size_d)
- {
- return -1;
- }
- utf8[len++] = 0xf0 | ( (int)wchar >> 18 );
- utf8[len++] = 0x80 | ( (wchar >> 12) & 0x3f );
- utf8[len++] = 0x80 | ( (wchar >> 6) & 0x3f );
- utf8[len++] = 0x80 | ( wchar & 0x3f );
- }
- }
- return len;
- }
- std::string s2utfs(const std::string& strSrc)
- {
- std::string strRes;
- std::wstring wstrUni = s2ws(strSrc);
- char* chUTF8 = new char[wstrUni.length() * 3];
- memset(chUTF8, 0x00, wstrUni.length() * 3);
- Uni2UTF(wstrUni, chUTF8, wstrUni.length() * 3);
- strRes = chUTF8;
- delete [] chUTF8;
- return strRes;
- }
- std::string utfs2s(const std::string& strutf)
- {
- std::wstring wStrTmp;
- UTF2Uni(strutf.c_str(), wStrTmp);
- return ws2s(wStrTmp);
- }
- #endif
給多人傳送HTML的demo2.cpp檔案如下
- #include <iostream>
- // 由於標頭檔案所處的位置是jwsmtp-1.32.15\jwsmtp\jwsmtp,所以,需要注意include的路徑
- #include "jwsmtp/jwsmtp.h"
- std::string html("<html>"
- "<body>"
- "This is the html part of the message<br><br>"
- "<b>bold</b><br>"
- "<i>italic</i><br>"
- "<font size=\"7\">Large Text</font><br><br>"
- "Or a link: <a href=\"http://johnwiggins.net\">johnwiggins.net</a><br><br>"
- "And an image: <br><img alt=\"an image in email\" src=\"http://johnwiggins.net/jwsmtp/example.png\"><br>"
- "</body>"
- "</html>");
- int main(int argc, char* argv[])
- {
- jwsmtp::mailer m(""/*接收者不填寫*/, "testjwstmp@163.com"/*傳送者*/, "這裡填寫郵件標題",
- "這裡填寫郵件內容", "smtp.163.com",
- jwsmtp::mailer::SMTP_PORT, false);
- //新增多個接收者
- m.addrecipient("testjwstmp@163.com");
- m.addrecipient("testjwstmp@gmail.com");
- m.addrecipient("testjwstmp@qq.com");
- //新增HTML的傳送內容,它會替換建構函式中的“這裡填寫郵件內容”
- m.setmessageHTML(html);
- //經過測試,163支援的auth認證是PLAIN模式
- m.authtype(jwsmtp::mailer::PLAIN);
- //這裡輸入認證使用者名稱,注意哦,需要是***@163.com的使用者名稱
- m.username("testjwstmp@163.com");
- //這裡輸入密碼
- m.password("******");
- m.send(); // 這裡傳送郵件,需要注意的是,這裡是同步模式哦!
- std ::cout << m.response() << std::endl;//這裡如果展示的是250,代表傳送郵件成功
- system("pause");
- return 0;
- }
附上傳送Email的返回碼
郵件服務返回程式碼含義
500 格式錯誤,命令不可識別(此錯誤也包括命令列過長)
501 引數格式錯誤
502 命令不可實現
503 錯誤的命令序列
504 命令引數不可實現
211 系統狀態或系統幫助響應
214 幫助資訊
220 服務就緒
221 服務關閉傳輸通道
421 服務未就緒,關閉傳輸通道(當必須關閉時,此應答可以作為對任何命令的響應)
250 要求的郵件操作完成
251 使用者非本地,將轉發向
450 要求的郵件操作未完成,郵箱不可用(例如,郵箱忙)
550 要求的郵件操作未完成,郵箱不可用(例如,郵箱未找到,或不可訪問)
451 放棄要求的操作;處理過程中出錯
551 使用者非本地,請嘗試
452 系統儲存不足,要求的操作未執行
552 過量的儲存分配,要求的操作未執行
553 郵箱名不可用,要求的操作未執行(例如郵箱格式錯誤)
354 開始郵件輸入,以.結束
554 操作失敗
535 使用者驗證失敗
235 使用者驗證成功
334 等待使用者輸入驗證信
相關文章
- spring email 傳送功能SpringAI
- Xamarin Essentials教程傳送郵件EmailAI
- 使用Apache commons email傳送郵件ApacheAI
- java 如何實現傳送郵件 email?JavaAI
- 使用oracle job定時傳送email郵件OracleAI
- 基於Spring Boot傳送 mailSpring BootAI
- 基於SpringBoot的策略模式demoSpring Boot模式
- 優化基於文字的資產的編碼和傳送大小優化
- python實現基於smtp傳送郵件Python
- [求助] 如何把 allure 的 index.html 所顯示的內容,展示在 jenkins 傳送的 Email 中?IndexHTMLJenkinsAI
- Java Mail 郵件傳送(一):入門DemoJavaAI
- Android 基於Netty的訊息推送方案之字串的接收和傳送(三)AndroidNetty字串
- 一個基於Android的MVP框架DemoAndroidMVP框架
- 如何將炫酷的報表直接截圖傳送郵件——在Superset 0.37使用Schedule Email功能AI
- 基於fullcalendar製作的日程管理小demo
- 直播平臺原始碼,簡訊驗證碼傳送demo原始碼
- 郵件的傳送
- 基於 WebRTC 實現自定義編碼解析度傳送Web
- 基於ThinkPHP5.0+GatewayWorker寫的一個聊天DEMOPHPGateway
- 【MM】基於收貨的發票校驗Bapi DemoAPI
- 基於c++的數學運算C++
- 一個基於 swoole 的非同步 mqtt 客戶端庫,可用於接收或者傳送 mqtt 協議的訊息非同步MQQT客戶端協議
- [iOS][OC] 開發利器:控制器傳送門VCPicker(附demo)iOS
- C++編寫自定義TCP包併傳送C++TCP
- Ubuntu的郵件傳送Ubuntu
- 基於SpringMVC的上傳圖片SpringMVC
- 基於WebUploader的圖片上傳Web
- 基於 EasyWechat 和 Laravel notification 傳送微信小程式模板訊息Laravel微信小程式
- C++ - tcp網路傳輸如何傳送結構體型別C++TCP結構體型別
- C/C++ 運用Npcap傳送UDP資料包C++PCAUDP
- HTML Email的編寫HTMLAI
- SOAPMessage的組成和傳送
- ton jetton 傳送字串的方式字串
- Go的Channel傳送和接收Go
- 一個基於Ionic3.x cordova的移動APP demoAPP
- Linux基礎命令---sendmail傳送郵件LinuxAI
- 基於OpenSSL的HTTPS通訊C++實現HTTPC++
- QFluentWidgets: 基於 C++ Qt 的 Fluent Design 元件庫C++QT元件
- C++ 實現基於TCP的聊天室C++TCP