|
由于業(yè)務(wù)上存在發(fā)送報(bào)警郵件的需求,一直想找一個(gè)簡單易用的發(fā)送Email的C++庫。
終于找到了,它就是jwSTMP(http:///projects/jwsmtp/)。
最新的jwSTMP版本(1.32.15)能夠跨平臺(tái)(BSD、Linux和Windows等)的支持以C++代碼或者C++庫的形式編碼發(fā)送Email。它可以發(fā)送附件、支持多個(gè)收件人(最多100個(gè)),支持CC(抄送)和BCC(隱藏性抄送);同樣的,它也支持以HTML的方式發(fā)送郵件。
我們知道發(fā)送Email有POP3和SMTP兩種方式。目前jwSTMP不支持POP3的方式。但是它提供了MX lookup方式,即直接得到目的地址的郵件交換服務(wù)器地址(MX)將郵件發(fā)送出去。
現(xiàn)在說說如何使用吧。
下載和編譯。請(qǐng)到sourceforge上將它下載下來。如果使用Windows平臺(tái),直接點(diǎn)擊工程文件即可(缺省是VC6的工程文件,我使用VS2008將工程文件轉(zhuǎn)化也是可以的)然后編譯即可;如果使用Linux,請(qǐng)執(zhí)行通行的三部曲:
./configure
make
make install
代碼修改。適合中國人的習(xí)慣,我將使用163的郵箱服務(wù)展示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"/*發(fā)送者*/, "這里填寫郵件標(biāo)題",
-
"這里填寫郵件內(nèi)容", "smtp.163.com",
-
jwsmtp::mailer::SMTP_PORT, false);
-
-
//經(jīng)過測試,163支持的auth認(rèn)證是PLAIN模式
-
m.authtype(jwsmtp::mailer::PLAIN);
-
-
//這里輸入認(rèn)證用戶名,注意哦,需要是***@163.com的用戶名
-
m.username("testjwstmp@163.com");
-
//這里輸入密碼
-
m.password("******");
-
m.send(); // 這里發(fā)送郵件,需要注意的是,這里是同步模式哦!
-
std ::cout << m.response() << std::endl;//這里返回是否成功,250代表發(fā)送郵件成功;
-
system("pause");
-
return 0;
-
}
需要注意的是,雖然我在測試時(shí)發(fā)送在cpp文件中寫入中文使用163.com發(fā)送是沒有出現(xiàn)亂碼的,但是,在公司中發(fā)送報(bào)警郵件則會(huì)出現(xiàn)亂碼。為了解決亂碼問題,需要使用網(wǎng)絡(luò)上有人提供的string s2utfs(const string& strSrc)函數(shù)進(jìn)行轉(zhuǎn)碼為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
給多人發(fā)送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://\"></a><br><br>"
-
"And an image: <br><img alt=\"an image in email\" src=\"http:///jwsmtp/example.png\"><br>"
-
"</body>"
-
"</html>");
-
-
int main(int argc, char* argv[])
-
{
-
jwsmtp::mailer m(""/*接收者不填寫*/, "testjwstmp@163.com"/*發(fā)送者*/, "這里填寫郵件標(biāo)題",
-
"這里填寫郵件內(nèi)容", "smtp.163.com",
-
jwsmtp::mailer::SMTP_PORT, false);
-
-
//添加多個(gè)接收者
-
m.addrecipient("testjwstmp@163.com");
-
m.addrecipient("testjwstmp@gmail.com");
-
m.addrecipient("testjwstmp@qq.com");
-
-
//添加HTML的發(fā)送內(nèi)容,它會(huì)替換構(gòu)造函數(shù)中的“這里填寫郵件內(nèi)容”
-
m.setmessageHTML(html);
-
-
//經(jīng)過測試,163支持的auth認(rèn)證是PLAIN模式
-
m.authtype(jwsmtp::mailer::PLAIN);
-
-
//這里輸入認(rèn)證用戶名,注意哦,需要是***@163.com的用戶名
-
m.username("testjwstmp@163.com");
-
//這里輸入密碼
-
m.password("******");
-
m.send(); // 這里發(fā)送郵件,需要注意的是,這里是同步模式哦!
-
std ::cout << m.response() << std::endl;//這里如果展示的是250,代表發(fā)送郵件成功
-
system("pause");
-
return 0;
-
}
附上發(fā)送Email的返回碼
郵件服務(wù)返回代碼含義
500 格式錯(cuò)誤,命令不可識(shí)別(此錯(cuò)誤也包括命令行過長)
501 參數(shù)格式錯(cuò)誤
502 命令不可實(shí)現(xiàn)
503 錯(cuò)誤的命令序列
504 命令參數(shù)不可實(shí)現(xiàn)
211 系統(tǒng)狀態(tài)或系統(tǒng)幫助響應(yīng)
214 幫助信息
220 服務(wù)就緒
221 服務(wù)關(guān)閉傳輸信道
421 服務(wù)未就緒,關(guān)閉傳輸信道(當(dāng)必須關(guān)閉時(shí),此應(yīng)答可以作為對(duì)任何命令的響應(yīng))
250 要求的郵件操作完成
251 用戶非本地,將轉(zhuǎn)發(fā)向
450 要求的郵件操作未完成,郵箱不可用(例如,郵箱忙)
550 要求的郵件操作未完成,郵箱不可用(例如,郵箱未找到,或不可訪問)
451 放棄要求的操作;處理過程中出錯(cuò)
551 用戶非本地,請(qǐng)嘗試
452 系統(tǒng)存儲(chǔ)不足,要求的操作未執(zhí)行
552 過量的存儲(chǔ)分配,要求的操作未執(zhí)行
553 郵箱名不可用,要求的操作未執(zhí)行(例如郵箱格式錯(cuò)誤)
354 開始郵件輸入,以.結(jié)束
554 操作失敗
535 用戶驗(yàn)證失敗
235 用戶驗(yàn)證成功
334 等待用戶輸入驗(yàn)證信
|