筆者在實驗郵件發送系統時開發了 SMailer(Simple Mail Sender),參考網路資源與網路程式設計書籍,保留自身特色:功能完整、結構精簡、標準 C++ 實作、物件導向設計良好。可直接整合至專案中使用。
採用標準 C++ 撰寫,類別職責分明,命名空間隔離:核心類別位於 SMailer 命名空間,工具類別位於 MUtils。
class MimeContent {
public:
MimeContent(const std::string content = "");
virtual std::string getType() const = 0;
virtual std::string getDisposition() const;
virtual std::string getTransEncoding() const = 0;
virtual std::string& getContent() = 0;
protected:
std::string _content;
};
// 三個具體實作類別:
// PlainTextContent - 純文字郵件本文
// TextHtmlContent - HTML 格式郵件本文
// AppOctStrmContent - 附件(Base64 編碼)
AppOctStrmContent::getContent() 延遲讀取檔案並 Base64 編碼:
std::string& AppOctStrmContent::getContent() {
MUtils::FileHelper::open(_file_name, _content);
_content = MUtils::Base64Helper::encode(_content);
return _content;
}
包含寄件者、多收件人(使用 std::multimap 支援同名)、主題、優先級、MIME 內容容器(std::vector<MimeContent*>)。提供統一介面新增/清除/取得本文與附件。
對 MailInfo 進一步封裝,產生符合 RFC 郵件格式的標頭、內容邊界、收件人列表。採用類迭代器模式遍歷收件人與 MIME 內容,介面直觀:
class MailWrapper {
public:
MailWrapper(MailInfo* mail_info);
std::string getSenderAddress();
std::string getHeader();
std::string getEnd();
void traverseReceiver(); bool hasMoreReceiver(); std::string nextReceiverAddress();
void traverseContent(); bool hasMoreContent(); std::string& nextContent();
private:
// 內部處理 From/To/Date/Name 編碼等細節
};
介面極簡:建構時傳入 SMTP 伺服器與驗證資訊,setMail() 設定 MailWrapper,sendMail() 發送。
Priority:三級優先級常數ErrorMessage:單例模式統一錯誤訊息管理MailException:繼承 std::exception 的例外類別FileHelper、WinSockHelper/WinSockException、Base64Helper:檔案 I/O、WinSock 封裝、Base64 編解碼SMailer/:核心 SMailer.h/.cppMUtils/:FileHelper.h、WinSockHelper.h、Base64Helper.h/.cppTestSMailer.cpp:命令列示範程式已在 MSVC6 與 Cygwin-b20 編譯通過,採用 STL 與 BSD 風格 Socket,移植至其他平台較容易。GUI 整合亦相當容易。