资源简介
用vmime收取邮件/解析邮件
用vmime收取邮件
vmime对邮件格式和邮件协议做了很好的封装,使用起来还是非常方便的。
vmime对于邮件协议都封装在vmime::net名字空间中,主要要用到的对象,有:
vmime::net::session,主要用于维护和服务器之间的连接
vmime::net::store,表示一个邮件存储,这是一个基类,没种邮件协议都有自己的store(如POP3Store,IMAPStore)
vmime::net::folder,表示邮件存储上的文件夹,和store一样,每种邮件协议,都有自己的folder实现
vmime::net::message,表示一封网络邮件,和vmime::message不同,vmime::net::message可能只有邮件的一部分,如邮件头等信息(由使用的邮件协议决定)。
vmime会根据session中设置的邮件协议,创建对应的store。
一些常用操作的实现(POP3协议):
连接邮箱:
vmime::utility::ref<vmime::net::session> session = vmime::create<vmime::net::session>(); //创建session
vmime::utility::ref<vmime::net::store> store = session->getStore(vmine_url); //获得store
store->connect();//连接
vmime::utility::ref<vmime::net::folder>folder = store->getDefaultFolder();//创建folder,路径是默认路径(inbox)
folder->open(vmime::net::folder::MODE_READ_WRITE);//以读写的形式打开
获取邮件:
std::vector<vmime::utility::ref<vmime::net::message> > allMessages = folder->getMessages();
folder->fetchMessages(allMessages, vmime::net::folder::FETCH_ENVELOPE); //获取所有邮件的头部信息,包含sender, recipients, date, subject
vmime::string mailContent;
vmime::utility::outputStreamStringAdapter out(mailContent);
resultMsg->extract(out); //找到需要的邮件后,下载到本地,保存到string中,这里vmime::string是std::string的typedef
删除邮件:
folder->deleteMessage(resultMsg->getNumber()); //执行删除指令
folder->close(true);//关闭文件夹,真正对邮件进行删除
使用当中出现的问题:
按照vmime-book中的例子,在获取邮件的时候,增加了vmime::net::folder::FETCH_FLAGS标签后,会抛出异常,提示不支持该操作。
还有执行了folder->deleteMessage函数之后,邮件没有真正删除。通过抓包和查看源代码后发现,deleteMessage函数是对邮件服务器发送了DELE指令,但是邮件服务器不会立即执行,需要QUIT之后才会真正的删除。而在folder的析构函数中,调用的是folder->close(false)函数来关闭文件夹的,这样在发送QUIT命令之前,会向邮件服务器发送一个RSET命令,将已经被标记为删除的邮件状态充值,所以不会真正的删除邮件。目前只有在执行了删除命令后,显式执行close(true)函数,确保马上发送QUIT命令,让服务器删除邮件。
上述命令真正执行的POP3命令为:
#连接
USER xxx #用户名
PASS xxx #密码
STAT #查询邮件数量和大小
TOP 1 0 #查看序号为1的邮件的头部
RETR 1 #接受第一封邮件的所有内容
DELE 1 #删除第一封邮件
QUIT #退出,服务器执行删除操作
vmime解析邮件
解析邮件相对比较简单,需要将收取的邮件,重新从字符串转换成vmime::message格式,然后就可以获取到自己需要部分的内容了。
首先将vmime::string格式转换为vmime::message:
vmime::utility::ref<vmime::message> mail = vmime::create<vmime::message>();
mail->parse(mailContent);
vmime还提供了一个简单的帮助类vmime::messageParser方便对message进行解析。
message主要包含了邮件头和邮件内容,内容又因为multi-part的邮件格式规定,被拆分成了多个vmime::textPart。通常使用到的textPart的子类,有vmime::htmlTextPart和vmime::plainTextPart,分别对应邮件body中的content-type为text/html和text/plain。
代码:
vmime::messageParser mp(mail);
for (int i = 0; i < mp.getTextPartCount(); i) //遍历所有的textPart
{
vmime::utility::ref<const vmime::textPart> text = mp.getTextPartAt(i);
if (text->getType().getSubType() == vmime::mediaTypes::TEXT_HTML) //text/html
{
vmime::utility::ref<const vmime::htmlTextPart> htmlText = text.dynamicCast<const vmime::htmlTextPart>();
vmime::utility::outputStreamStringAdapter htmlOut(htmlContent);
vmime::utility::charsetFilteredOutputStream utf8Out(htmlText->getCharset(), vmime::charset(“utf-8″), htmlOut); //强制转换正文为utf8编码
htmlText->getText()->extract(utf8Out);
utf8Out.flush();
}
else if (text->getType().getSubType() == vmime::mediaTypes::TEXT_PLAIN) //text/plain
{
vmime::utility::ref<const vmime::plainTextPart> plainText = text.dynamicCast<const vmime::plainTextPart>();
vmime::utility::outputStreamStringAdapter plainOut(plainTextContent);
vmime::utility::charsetFilteredOutputStream utf8Out(plainText->getCharset(), vmime::charset(“utf-8″), plainOut);
plainText->getText()->extract(utf8Out);
utf8Out.flush();
}
}
对于html个是的邮件正文,还可以遍历获取里面的embeddedObject,如嵌入的附件图片等,不过目前没有这样的需求,就没有去尝试了。
在真正执行的时候,又发现了一个问题,必须在开始使用前,调用vmime::platform::setHandler<vmime::platforms::posix::posixHandler>();设置平台相关的handler,这里设置的是符合posix的平台,windows貌似也有对应的handler。
代码片段和文件信息
using System;
using System.xml;
using System.xml.XPath;
using System.IO;
using System.Collections.Generic;
using System.Text;
namespace CertCompressor
{
class Program
{
///
/// Purpose:
/// - Read all PEM files and write them into one TXT file
/// - Read mime types from xml file and convert to INI format
///
static void Main(string[] args)
{
Console.SetBufferSize(100 5000);
StringBuilder s_Text = new StringBuilder(100000);
String s_WorkDir = Directory.GetCurrentDirectory();
int Pos = s_WorkDir.IndexOf(“\\Converter\\“);
if (Pos < 0)
throw new Exception(“Invalid directory. This program must run in \“...\\Converter\\
属性 大小 日期 时间 名称
----------- --------- ---------- ----- ----
目录 0 2013-12-26 21:56 Vmime.NET
目录 0 2013-12-26 21:51 Vmime.NET\libvmime
文件 1531 2015-11-21 08:36 Vmime.NET\_CleanAll.cmd
目录 0 2014-01-02 15:20 Vmime.NET\Converter
文件 1959 2013-12-29 13:28 Vmime.NET\Converter\Converter.csproj
目录 0 2013-12-29 12:29 Vmime.NET\Converter\MimeTypes
文件 163065 2013-12-29 12:29 Vmime.NET\Converter\MimeTypes\mime.xm
文件 10330 2014-01-26 21:11 Vmime.NET\Converter\Program.cs
目录 0 2014-01-02 15:20 Vmime.NET\Converter\Release
文件 20480 2014-01-26 21:11 Vmime.NET\Converter\Release\Converter.exe
目录 0 2013-12-26 22:12 Vmime.NET\Converter\RootCertificates
文件 1406 2013-12-26 12:25 Vmime.NET\Converter\RootCertificates\A-Trust-nQual-03.pem
文件 1542 2013-12-26 12:28 Vmime.NET\Converter\RootCertificates\AAACertificateServices.pem
文件 2074 2013-12-26 12:29 Vmime.NET\Converter\RootCertificates\ACEDICOMRoot.pem
文件 2318 2013-12-26 12:32 Vmime.NET\Converter\RootCertificates\ACRaízCerticámaraS.A..pem
文件 2082 2013-12-26 18:18 Vmime.NET\Converter\RootCertificates\ActalisAuthenticationRootCA.pem
文件 1504 2013-12-26 12:26 Vmime.NET\Converter\RootCertificates\AddTrustClass1CARoot.pem
文件 1546 2013-12-26 12:26 Vmime.NET\Converter\RootCertificates\AddTrustExternalCARoot.pem
文件 1500 2013-12-26 12:26 Vmime.NET\Converter\RootCertificates\AddTrustPublicCARoot.pem
文件 1514 2013-12-26 12:26 Vmime.NET\Converter\RootCertificates\AddTrustQualifiedCARoot.pem
文件 1224 2013-12-26 12:26 Vmime.NET\Converter\RootCertificates\AffirmTrustCommercial.pem
文件 1224 2013-12-26 12:26 Vmime.NET\Converter\RootCertificates\AffirmTrustNetworking.pem
文件 1922 2013-12-26 12:26 Vmime.NET\Converter\RootCertificates\AffirmTrustPremium.pem
文件 766 2013-12-26 12:26 Vmime.NET\Converter\RootCertificates\AffirmTrustPremiumECC.pem
文件 1344 2013-12-26 12:26 Vmime.NET\Converter\RootCertificates\AmericaOnlineRootCertificationAuthority1.pem
文件 2050 2013-12-26 12:26 Vmime.NET\Converter\RootCertificates\AmericaOnlineRootCertificationAuthority2.pem
文件 1340 2013-12-26 12:31 Vmime.NET\Converter\RootCertificates\ApplicationCA-JapaneseGovernment.pem
文件 1592 2013-12-26 12:27 Vmime.NET\Converter\RootCertificates\AutoridaddeCertificacionFirmaprofesionalA.pem
文件 2202 2013-12-26 12:27 Vmime.NET\Converter\RootCertificates\AutoridaddeCertificacionFirmaprofesionalB.pem
文件 1282 2013-12-26 12:27 Vmime.NET\Converter\RootCertificates\BaltimoreCyberTrustRoot.pem
............此处省略819个文件信息
- 上一篇:简易电子病历编辑器
- 下一篇:c#微信用户授权登录
相关资源
- WPF写的获取外部公网IP地址及发送邮件
- C#做的SMTP邮件收发程序
- c#邮件发送
- asp.netC#发送电子邮件
- C#使用POP3协议构建客户端邮件接收源
- C#邮件接收案例源码.rar
- ASP.NETC#邮件收发管理系统论文及毕业
- 基于C#邮件客户端
- 邮件发送程序设计与实现
- asp.netC#定时发送邮件
- C#使用SMTP服务器发送邮件
- C# WinForm 邮件发送支持多附件可群发
- C# POP3接收邮件程序(可用)
- C#邮件接收案例源码--(201903)
- C# Nlog日志使用并发送邮件
- C# 基于SMTP协议和SOCKET发送邮件及附件
- 电子邮件email收取客户端程序,C#源代
- asp.net用OpenPop.dll获取邮件列表和内容
- C# 实现简单邮件SMTP和POP3客户端 联系
- asp.net 站内邮件系统c#
- 一套基于C#开发的收发邮件系统完整版
- 简单的电子邮件收发系统
- C#.net发送邮件完整源代码DEMO完整版
- c# Imap收信组件,UTF-8版本,完美支持
- C#编写简单的邮件客户端支持POP3,S
- c# SMTP邮件发送程序,如不好用,我撞
- C# socket smtp 邮件发送(支持SSL)源码
- C# pop3 邮件接收程序
- C# 邮件群发示例 源码下载18952
- winds服务,发送邮件且禁用违法规则的
评论
共有 条评论