Qt + CURL + mimetic 发送邮件(带附件)

时间:2021-08-29 06:34:13

使用了大名鼎鼎的CURL 开源库,以及mimetic开源库。

CURL支持N多协议。功能超强,但是不能直接发邮件附件,需要自己拼mime。太麻烦,于是乎~~

mimetic主要用于构造邮件mimetic格式数据。

CURL:http://curl.haxx.se/

mimetic:http://www.codesink.org/mimetic_mime_library.html

源码:http://download.csdn.net/detail/kfbyj/6566431

	m_Email.SetUserInfo("你的邮箱帐号", "你的邮箱密码");
m_Email.SetHost("smtp://smtp.163.com"); //你的邮箱smtp服务器地址
m_Email.AddReceiver("<XXXX@163.com>"); //添加一个接受邮件者
m_Email.AddAttach("附件绝对路径"); //添加一个附件
m_Email.SetSend("邮件主题", "邮件内容", "联系方式");
m_Email.start(); //开始发送,,线程
/************************************************************************/
/* author : 狂风暴雨
* date : 2013年11月14日 14:11:49
* desc : 一份邮件的线程
* */
/************************************************************************/ #ifndef EMAIL_H
#define EMAIL_H #include "third_party/curl/curl.h" #include <QStringList>
#include <QObject>
#include <QThread> class Email : public QThread
{
Q_OBJECT public:
Email(QObject *parent);
~Email(); //发送一封右键
void run(); void SetSend(const QString& subject, const QString& content, const QString& contact); //设置服务器地址
void SetHost(const QString& host) { m_smtpServer = host;}
QString Host() {return m_smtpServer;} //设置用户密码
void SetUserName(const QString& name);
QString UserName() { return m_userName;} void SetPassword(const QString& password);
QString Password() { return m_passWord;} void SetUserInfo(const QString& name, const QString& password); //添加收信人,返回收信人数目
int AddReceiver(const QString& receiver);
QStringList Receiver() { return m_receiverList;} //附件
int AddAttach(const QString& attachPath);
QStringList Attachs() { return m_attachsList;}
void RemoveAttach(int index); int Result() {return m_res;} //重置
void Reset();
signals:
void signalSendResult(int); private:
CURLcode m_res; //主题
QString m_subject;
QString m_content;
QString m_contact; //用户密码
QString m_userName;
QString m_passWord; //stmp 服务器
QString m_smtpServer; //接受人列表
QStringList m_receiverList; //附件列表
QStringList m_attachsList; static int ReadData(void* ptr, size_t size, size_t nmemb, void* userp);
}; #endif // EMAIL_H

==============================================================================================================================
==============================================================================================================================


#include "email.h"
#include "third_party/mimetic/mimetic.h"
#include "utils/utils.h" struct UserData
{
std::stringstream ss;
size_t total;
UserData() : total(0),
ss()
{}
}; Email::Email(QObject *parent)
: QThread(parent)
{
m_receiverList.clear();
m_attachsList.clear();
} Email::~Email()
{ } void Email::run()
{
mimetic::MultipartMixed head;
head.header().from(utils::QStringToUtf8String(m_userName));
head.header().subject(utils::QStringToUtf8String(m_subject));
head.header().push_back(mimetic::Field("Mime-Version","1.0"));
struct curl_slist *slist = NULL;
for (int i = 0; i < m_receiverList.size(); ++i)
{
slist = curl_slist_append(slist, utils::QStringToUtf8String(m_receiverList.at(i)).c_str());
head.header().to(utils::QStringToUtf8String(m_receiverList.at(i)).c_str());
} //添加邮件内容
mimetic::MimeEntity* pMeContent = new mimetic::MimeEntity;
pMeContent->body().assign(utils::QStringToUtf8String(m_content + tr("\nContact Info:") + m_contact));
head.body().parts().push_back(pMeContent); //如果有附件添加附件
for (int i = 0; i < m_attachsList.size(); ++i)
{
mimetic::MimeEntity* pMe = new mimetic::MimeEntity;
pMe->header().push_back(mimetic::Field("Content-Transfer-Encoding","base64"));
FILE *pfile = fopen(utils::QStringToUtf8String(m_attachsList.at(i)).c_str(), "rb");
char buffer[4096];
uint32_t totalreadbytes = 0;
while (!feof(pfile))
{
uint32_t readbytes = fread(buffer, 1, 4096, pfile);
if (ferror(pfile) || readbytes == 0)
break; totalreadbytes += readbytes;
mimetic::Base64::Encoder b64;
std::stringstream temp;
std::ostreambuf_iterator<char> out(temp);
//转为BASE64编码,目标存放至std::stringstream中
mimetic::code(buffer, buffer + readbytes, b64, out);
std::string str = temp.str();
std::cout<<str;
pMe->load(str.begin(), str.end(), mimetic::imNone);
}
fclose(pfile);
QString fileName = utils::PathFindFileName(m_attachsList.at(i));
pMe->header().push_back(mimetic::Field(
utils::QStringToUtf8String("Content-Type: application/octet-stream; name=" +
fileName)));
pMe->header().push_back(mimetic::Field(utils::QStringToUtf8String("Content-Disposition : attachment; filename=" +
fileName)));
head.body().parts().push_back(pMe);
} struct UserData ud;
ud.ss<<head;
ud.ss.seekg(0, std::ios::end);
ud.total = ud.ss.tellg();
ud.ss.seekg(0, std::ios::beg); CURL *curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, utils::QStringToUtf8String(m_smtpServer).c_str());
curl_easy_setopt(curl, CURLOPT_USERNAME, utils::QStringToUtf8String(m_userName).c_str());
curl_easy_setopt(curl, CURLOPT_PASSWORD, utils::QStringToUtf8String(m_passWord).c_str());
curl_easy_setopt(curl, CURLOPT_MAIL_FROM, utils::QStringToUtf8String(m_userName).c_str()); //发送者
curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, slist);
curl_easy_setopt(curl, CURLOPT_READDATA, &ud);
curl_easy_setopt(curl, CURLOPT_READFUNCTION, ReadData);
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
} m_res = curl_easy_perform(curl);
curl_slist_free_all(slist);
curl_easy_cleanup(curl);
} void Email::SetSend(const QString& subject, const QString& content, const QString& contact)
{
m_subject = subject;
m_contact = contact;
m_content = content;
} void Email::Reset()
{
m_userName.clear();
m_passWord.clear();
m_smtpServer.clear();
m_receiverList.clear();
m_attachsList.clear();
} void Email::SetUserName(const QString& name)
{
m_userName = name;
} void Email::SetPassword(const QString& password)
{
m_passWord = password;
} void Email::SetUserInfo(const QString& name, const QString& password)
{
m_userName = name;
m_passWord = password;
} int Email::AddReceiver(const QString& receiver)
{
m_receiverList.append(receiver);
return m_receiverList.size();
} int Email::AddAttach(const QString& attachPath)
{
m_attachsList.append(attachPath);
return m_attachsList.size();
} void Email::RemoveAttach(int index)
{
m_attachsList.removeAt(index);
} int Email::ReadData(void* ptr, size_t size, size_t nmemb, void* userp)
{
struct UserData * pstream = static_cast<struct UserData *>(userp);
if (pstream->ss.eof())
return 0; size_t before = pstream->ss.tellg();
pstream->ss.read((char*)ptr, size*nmemb);
size_t after = pstream->ss.tellg();
if (pstream->ss.eof())
return pstream->total - before;
return after - before;
}