首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C++ Builder 實戰:基於 Indy 與 Access 的電子郵件群發系統

     編輯:關於C++

郵件群發廣泛應用於電子商務行銷、企業通知、資訊訂閱。本文詳述使用 C++ Builder 整合 Indy 元件套件與 Access 2000 資料庫,實作支援 SMTP/ESMTP 認證的郵件群發系統。

郵件傳輸協定基礎

SMTP (RFC 821)

核心角色:SMTP 寄信機 ↔ 收信機。指令/回應模式:MAIL FROM: <addr> → 250 OK。主要指令:HELO、MAIL FROM、RCPT TO、DATA、QUIT。

ESMTP 認證擴展 (RFC 2554)

防垃圾郵件需求下,幾乎所有郵件服務商要求認證。ESMTP 新增 AUTH 指令,支援機制:

  • LOGIN:Base64 編碼帳號/密碼(最常用,但明文等價)
  • CRAM-MD5:挑戰-回應機制,密碼不傳輸
  • PLAIN:明文傳輸

認證流程:連接 → AUTH LOGIN → 伺服器回應 Base64 "Username:" → 客戶端回應 Base64 帳號 → 伺服器回應 "Password:" → 客戶端回應 Base64 密碼 → 成功進入郵件傳送階段。

系統架構設計

整體架構:C++ Builder + Indy TIdSMTP + Access 2000 (ADO)
  • 郵件清單管理:Access 2000 資料庫,ADO (TADOTable) 動態連接
  • SMTP 通訊:Indy 10 TIdSMTP + TIdMessage
  • 認證支援:LOGIN 機制(可擴充 CRAM-MD5)

關鍵元件屬性與方法

TIdSMTP說明
HostSMTP 伺服器位址 (如 smtp.gmail.com)
Port通常 25、465(SSL)、587(STARTTLS)
AuthenticationTypeatLogin 等
UserId / Password帳號密碼
Connect() / Disconnect()建立/關閉會話
Send(TIdMessage*)發送郵件
TIdMessage說明
ContentType如 "text/html" (關鍵!否則正文變附件)
Subject主旨
Body正文內容
From->Name寄件人顯示名稱
Recipients->EmailAddresses收件人清單

ADO 存取 Access 資料庫

void __fastcall TForm1::N_OpenClick(TObject *Sender) {
    AnsiString ConnStr;
    try {
        ADOTable1->Active = false;
        OpenDialog1->InitialDir = ".\\";
        OpenDialog1->Filter = "MDB檔案 (*.mdb)|*.mdb|所有檔案 (*.*)|*.*";
        OpenDialog1->DefaultExt = "mdb";
        if (OpenDialog1->Execute()) {
            // 必須包含 Jet OLEDB:Database Password 與 Persist Security Info
            ConnStr = "Provider=Microsoft.Jet.OLEDB.4.0; "
                     "Jet OLEDB:Database Password=" + MaskEdit1->Text.Trim() + "; "
                     "Data Source=" + OpenDialog1->FileName.Trim() + "; "
                     "Persist Security Info=True";
            ADOTable1->ConnectionString = ConnStr.Trim();
            ADOTable1->Active = true;
        }
    } catch (Exception &e) {
        Application->ShowException(&e);
    }
}

關鍵點:有密碼的 MDB 必須獨佔模式開啟,Persist Security Info=True 為必需。

群發核心程式碼

void __fastcall TForm1::SEND_BTNClick(TObject *Sender) {
    int recnum, k; AnsiString addr;
    
    IdSMTP1->Host = ComboBoxaddr->Text.Trim();
    IdSMTP1->Port = 25;
    if (CheckBox_AUTH->Checked) {
        IdSMTP1->AuthenticationType = atLogin;
        IdSMTP1->UserId = Edit_name->Text.Trim();
        IdSMTP1->Password = MaskEdit_pass->Text.Trim();
    }
    
    IdMessage1->ContentType = "text/html";  // 必須設定!
    IdMessage1->Subject = Edit3->Text.Trim();
    // ... 設定 Body、From 等 ...
    
    ADOTable1->First();
    recnum = ADOTable1->RecordCount;
    for (k = 0; k <= recnum - 1; k++) {
        addr = Trim(ADOTable1->FieldByName("Email")->AsString);
        IdMessage1->Recipients->EmailAddresses = addr;
        
        if (!IdSMTP1->Connected()) {
            try { IdSMTP1->Connect(); }
            catch (Exception &e) { 
                Application->MessageBox(e.Message.c_str(), "連接失敗", MB_ICONWARNING); 
                continue; 
            }
        }
        if (IdSMTP1->Connected()) {
            try { IdSMTP1->Send(IdMessage1); }
            catch (Exception &e) { 
                Application->MessageBox(e.Message.c_str(), "發送失敗", MB_ICONWARNING); 
            }
        }
        ADOTable1->Next();
    }
    Application->MessageBox("發送完成!", "郵件系統", MB_OK);
}

效能優化建議

  • 少量收件人(<50):單次 RCPT TO 多位址(逗號分隔)
  • 大量收件人:分批發送,避免單一郵件過大導致延遲或被退信
  • 考慮非同步發送佇列,避免 UI 凍結

安全性提醒

LOGIN 機制 Base64 非加密,生產環境建議:

  • 使用 SSL/TLS 加密通道 (Indy TIdSSLIOHandlerSocketOpenSSL)
  • 支援 CRAM-MD5 或 OAuth 2.0
  • 參考 Synapse 庫 (ararat.cz/synapse) 實作更多認證機制
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved