您的位置:首页 > 大数据 > 人工智能

VC下使用JMail实现邮件收发

2014-04-11 13:25 267 查看
最近需要写一个邮件发送与接收的模块。C++写这种东西还是比较纠结的,有以下几种办法:
1. 手写SMTP、POP3再加Winsock:太繁琐,写完后健壮性、扩展性都没法保证,写着练习还可以,商业用途就不合适了。
2. 用MS的MAPI(包括SMAPI):需要Outlook之类的支持,稳定性差(尤其是smapi,都淘汰了),不易学习。
3. 用一些命令行的邮件客户端,再写个C++的壳子:没找到好用的,windows版的msmtp、febootimail都不给力啊。
4. 如果单纯收发文本邮件,用telnet与邮箱服务器进行交互:直接用window的telnet服务,没法在C++里进行交互啊(反正我不会)。
5.用一些邮件组件,例如JMail:原本用了个免费版的JMail,啥功能都没有,就知道报异常。好在我们天朝上国盗版横行,搜了个专业版,瞬间闪亮。 给个链接:http://www.rayfile.com/files/c0554728-6bbe-11e0-9cb8-0015c55db73d/

//// 邮件接收代码

bool recvMail()
{
jmail::IMessagesPtr pMsgs; // 邮件集合
jmail::IMessagePtr pMsg;
jmail::IPOP3Ptr pPOP3("JMail.POP3");
pPOP3->Timeout = 30; // 30S超时,默认为120s

try
{
pPOP3->Connect("test_name","test_pass","pop.sina.com",110); // 连接pop服务器 端口110
pMsgs = pPOP3->Messages;
long mailNum = pMsgs->Count - 1; // 已下载邮件实际个数(0是未用的,故-1)
// 遍历每封邮件
for (long i=1; i<=mailNum; i++)
{
pMsg = pMsgs->Item[i]; // 提取第I封信件
_bstr_t sender = pMsg->From; // 发信人
_bstr_t subject = pMsg->Subject; // 发信主题
_bstr_t body = pMsg->Body; // 发信内容
cout<<"Email No."<<i<<endl // 输出邮件正文
<<"Sender: "<<((char*)sender!=NULL ? sender : "NULL")<<endl
<<"Subject: "<<((char*)subject!=NULL ? subject : "NULL")<<endl
<<"Body: "<<((char*)body!=NULL ? body : "NULL")<<endl;
jmail::IAttachmentsPtr atts = pMsg->Attachments; // 获取附件列表
long attNum = atts->Count;
cout<<"Attachment Num: "<<attNum<<endl; // 输出并下载所有附件
for(long j=0; j<attNum; j++)
{
cout<<"Att"<<j<<" Name: "<<atts->Item[j]->Name<<" Size: "<<atts->Item[j]->Size<<endl;
atts->Item[j]->SaveToFile(atts->Item[j]->Name); // 与已有文件同名会引起异常
}
cout<<"\n\n";
pMsg.Release();
}
pMsgs.Release(); // 释放资源、断开连接
pPOP3->Disconnect();
}
catch(_com_error e)
{
cout<<"Error Info: "<<e.ErrorMessage()<<"\nError Description: "<<e.Description()<<"\n";
return false;
}
return true;
}
//// 邮件发送代码
bool sendMail()
{
/// SMTP服务器设置
const char* smtpServer = "smtp.sina.com"; // smpt服务器
const char* username = "test_name"; // 用户名
const char* password = "test_pass"; // 密码
/// 发信内容设置
const char* sender = "test_name@sina.com"; // 发件邮箱,不能虚假填写
const char* senderName = "BlueStar"; // 显示的发件人名称,随意
const char* subject = "A test mail from bluestar"; // 邮件主题
const char* body = "The content of this mail\n"; // 邮件正文
const char* attachFiles[] = {"atts\\p1.jpg", "atts\\p2.jpg"}; // 附件列表,相对、绝对路径 both ok
/// 收信端设置
const char* recipients[] = {"recver1@163.com", "recver2@yeah.net", "recver3@yeah.net"}; // 收件邮箱列表
const char* recipientNames[] = {"rock", "bluestar", "whoown"}; // 收信人名称

/// 初始化JMail中Message对象
jmail::IMessagePtr pMsg("JMail.message");

pMsg->Priority = 3; // 优先级设置,1-5逐次降低, 3为中级
pMsg->Charset = "GB2312"; // 编码方式设置, 默认是iso-8859-1

pMsg->From = sender; // 发件人
pMsg->FromName = senderName; // 发件人姓名
int sz = sizeof(recipients) / sizeof(recipients[0]), i; // 添加所有收件人
for(i=0; i<sz; i++)
{
pMsg->AddRecipient(recipients[i], recipientNames[i], "");
}
pMsg->Subject = subject; // 主题
pMsg->Body = body; // 正文
pMsg->AppendText("You can add any words when you want\n"); // 可再添加一些正文
sz = sizeof(attachFiles) / sizeof(attachFiles[0]); // 添加所有附件
for(i=0; i<sz; i++)
{
pMsg->AddAttachment(attachFiles[i], VARIANT_FALSE, ""); // 参数3为文件类型
}

/// 发送邮件
try
{
pMsg->Send("test_name:test_pass@smtp.sina.com", VARIANT_FALSE);
}
catch(_com_error e)
{
cout<<"Error Info: "<<e.ErrorMessage()<<"\nError Description: "<<e.Description()<<"\n";
return false;
}
return true;
}

感谢几个关于JMail的博客地址:
http://www.vckbase.com/document/viewdoc/?id=684
http://tech.ddvip.com/2006-04/11440901403238.html
http://xiaoyueweiguang.blog.163.com/blog/static/1172675562011020105840807/
JMail的官方文档链接:
http://www.dimac.net/default2.asp?M=Products/MenuCOM.asp&P=Products/w3JMail/start.htm


一篇关于多线程下使用JMail 的帖子:
http://topic.csdn.net/u/20081006/10/13a5cee3-c7a6-4aae-9aa3-8d6ca285bd61.html

简单而言:CoInitialize(NULL)和CoUninitialize() 的作用域是基于线程的,所以必须在每个线程中都作COM初始化。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: