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

    使用了大名鼎鼎的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("
Contact 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;  
}
原文地址:https://www.cnblogs.com/fuhaots2009/p/3429305.html