摘 要:本文簡單闡述了發送電子郵件的原理,提出了一種基於C++ Builder和Access2000數據庫來實現電子郵件群發的方法,詳細介紹了C++ Builder 中TIdSMTP組件的使用,並給出了用TIdSMTP組件實現群發的核心示例代碼。
關鍵詞:電子郵件群發;認證;TIdSMTP;TIdMessage;ADO
引言 郵件群發這一手段被廣泛應用於電子商務、網絡營銷中,例如我們現在能夠通過chnia-pub.com(互動出版網)的書訊群發郵件了解到當前新書的資訊,據統計在美國有超過70%的Internet用戶的在線購物行為要歸功於Email營銷,另外那些建設了局域網的單位也可以通過郵件群發來發送通知或傳達文件,這樣能夠節省大量的人力物力而且方便迅速。本文簡單介紹了發送電子郵件的原理,提出了一種基於C++Builder和Access2000數據庫實現電子郵件群發的方法,詳細介紹了C++Builder 中TIdSMTP組件的使用,並給出了用TIdSMTP組件實現群發的核心示例代碼。
發送電子郵件的原理 1、SMTP協議
SMTP協議是IETF(Internet Engineering Task Force)制訂的有關電子郵件系統的標准協議組中的一員,它的目的就是實現有效(efficiently)和可靠的(reliably)郵件傳輸,主要對怎樣將電子郵件從發送方地址傳送到接收方地址,也就是對傳輸的規則做了規定。SMTP協議中的主要角色是SMTP發信機和SMTP收信機,但是一個SMTP服務器可能兼有兩種角色。SMTP協議采用了一組簡單的命令來建立連接並在主機之間傳送命令和數據。SMTP發信機向SMTP收信機發出SMTP命令,如:"MAIL FROM: <
[email protected]>"就是告知SMTP收信機郵件的來源,待收到命令後SMTP收信機則會響應應答SMTP命令,即會返回一個應答碼,應答碼一般為一個三位的十進制數,而且每一個數都有特定含義的,例如返回"250"表示要求的郵件操作完成。其他的SMTP命令和應答碼在RFC821中有詳細的描述,此處不再贅述。
2、ESMTP協議
目前,為了防止網絡上垃圾郵件的泛濫,幾乎所有的郵件服務提供商都在原來的SMTP服務器上追加了認證功能,但實際上SMTP協議本身並不具有認證的功能,在1999年3月出台的SMTP服務認證功能擴展(SMTP Service Extension for Authentication,RFC2544),即ESMTP中才定義了怎樣在SMTP客戶端與服務器之間來建立一種認證機制,執行認證協議的交換,同時擴展也為以後的協議交互進行了安全層的協商。該擴展是簡單認證和安全層(Simple Authentication and Security Layer,SASL)的一個方面。
SMTP認證功能的擴展實際實際上是增加了AUTH命令,AUTH命令的認證方式主要有LOGIN、CRAM-MD5和PLAIN等幾種,我國目前使用得比較多的是LOGIN方式認證。SMTP認證一般是在發送郵件之前進行一次,采用口令-應答(Challenge-Response)方式,即由服務器發送命令要求客戶端回答,客戶端根據服務器發送信息進行回答,如果應答通過了,則認證成功,即可繼續下一步處理。
用C++Builder實現郵件群發 1、總體設計
要實現郵件群發,我們首先需要實現與SMTP服務器連接,然後才能通過SMTP服務器發送郵件,由於SMTP服務器可能需要身份認證所以我們要編寫實用的郵件群發軟件還必須使其具有SMTP認證的功能。我們可以通過C++Builder中的TIdSMTP組件來實現與SMTP服務器的認證、連接和郵件的發送。通過編寫代碼循環讀取郵件地址列表(Mail List)中的郵件地址並發送郵件從而實現群發。考慮到管理和獲取郵件地址的方便性,地址列表存儲的安全性以及基於該郵件地址列表的其他相關應用程序的開發我們可以采用Access2000數據庫來存儲郵件地址列表,利用C++Builder中的TADOTable組件我們可以使用ADO方式輕松的實現對Access2000數據庫的直接訪問和各種操作。
2、郵件地址數據庫ADO方式訪問示例
C++Builder在數據庫處理方面向來是具有自己的優勢,一般我們都采用Borland的強大的BDE數據庫引擎來訪問和維護數據庫,但是使用BDE引擎有一個非常不方便的地方就是不能在程序運行階段動態指定數據源,而采用ADO(ActiveX Data Objects)方式具有高性能、高兼容性和高靈活性的特點。采用ADO方式我們既可以在程序設計階段指定數據源也可以在運行時動態修改數據源,而在實際應用中用戶可能會要動態的指定存儲郵件地址的數據庫,為了使編寫的群發程序具有更好得實用性,所以我選擇使用C++Builder中的ADO組件TADOTable來訪問和操作Access2000數據庫,具體示例代碼如下:
Void __fast call TForm1: N_OpenClick (TObject *Sender)
{
AnsiString ConnStr;
Try {ADOTable1->Active = false;
OpenDialog1->InitialDir =".\" ; //初始化打開對話框
OpenDialog1->Filter = "MDB郵件列表文件 (*.mdb)|*.mdb|所有文件 (*.*)|*.*";
OpenDialog1->DefaultExt = String("mdb");
if(OpenDialog1->Execute ())//動態指定數據源
{
ConnStr=" Provider=Microsoft.Jet.OLEDB.4.0; Jet OLEDB: Database Password =" + MaskEdit1->Text. Trim () + "; Data Source = " + OpenDialog1-> Filename. Trim () +"; Persist Security Info=True";
ADOTable1->Connection String =ConnStr.Trim ();
ADOTable1->Active=true;
}
Catch (Exception &exception)
{
Application->Show Exception (&exception);
}
}
注意代碼中加粗的部分是必須的,在訪問有密碼保護的Access2000數據庫時必須以獨占方式打開,如果沒有加粗部分的代碼,則連接數據庫時會提示錯誤。