天天看點

使用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 #退出,伺服器執行删除操作

轉載自:https://coolex.info/blog/108.html