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

Java 實作防毒郵件閘道:雙程式協作架構完整解析

     編輯:Java 相關知識

系統架構概覽

本方案採雙程式協作模式,搭配外部防毒掃描器,構建「公用信箱 → 病毒掃描 → 祕密信箱」的郵件防護管道:

  • VirPro01a:從 POP3 伺服器下載郵件,存入本地工作資料夾待掃描
  • 防毒軟體:掃描工作資料夾,清除或隔離帶毒郵件
  • VirPro01b:將安全郵件轉寄至祕密 SMTP 信箱,並從 POP3 伺服器刪除原信、歸檔備份

VirPro01a:POP3 郵件下載器

核心流程

  1. 建立 Socket 連線至 POP3 伺服器(Port 110)
  2. 傳送 USER/PASS 進行認證
  3. 進入 TRANSACTION 狀態,發送 STAT 取得信件數
  4. 逐封發送 UIDL n 取得唯一 ID,作為本地檔名
  5. 發送 RETR n 下載完整郵件內容,存入 ./Messages/ 資料夾
  6. GUI 提供「Start/Next」按鈕手動控制下載節奏,避免封鎖事件派發執行緒

關鍵程式碼片段:下載迴圈

outputStream.println("UIDL " + msgNumber);
String uidl = validateOneLine(); // 格式:"+OK 38 402fb6da00000098"

pathFileName = dataPath + uidl;
DataOutputStream dataOut = new DataOutputStream(new FileOutputStream(pathFileName));

outputStream.println("RETR " + msgNumber);
validateOneLine(); // 忽略 +OK 回應
String msgLine = inputStream.readLine();
while (!msgLine.equals(".")) { // 單獨一行 "." 代表郵件結束
    dataOut.writeBytes(msgLine + "\n");
    msgLine = inputStream.readLine();
}
dataOut.close();
// 觸發下一封下載(模擬按鈕點擊)
Toolkit.getDefaultToolkit().getSystemEventQueue()
    .postEvent(new ActionEvent(startButton, ActionEvent.ACTION_PERFORMED, "Start/Next"));

VirPro01b:SMTP 轉寄與清理器

核心流程

  1. 掃描 ./Messages/ 所有檔案,逐一呼叫 forwardEmailMsg()
  2. 使用 Sun 內部類 sun.net.smtp.SmtpClient 發送郵件(SDK 1.4.2 內建但未公開文件化)
  3. 在 Subject 標頭前插入原始信件編號標記 {001} 以利追蹤
  4. 轉寄成功者加入 msgToDelete 向量,失敗者保留於工作資料夾
  5. 使用者確認後點擊「Delete Msg On Server」,發送 DELE n 標記刪除,再送 QUIT 生效
  6. 呼叫 moveFile() 將已處理檔案移至 ./Archives/ 歸檔

forwardEmailMsg 關鍵實作

private boolean forwardEmailMsg(String recipient, String smtpServer,
                                String tag, String pathFileName) {
    try {
        SmtpClient smtp = new SmtpClient(smtpServer);
        smtp.from(recipient);      // 寄件人設為收件人(僅需合法格式)
        smtp.to(recipient);        // 真正收件人
        PrintStream msg = smtp.startMessage();

        // 讀取完整郵件內容(含標頭與本文)
        StringBuffer message = new StringBuffer(readLines(pathFileName, null, null));
        // 在 Subject: 後插入標記
        int idx = message.indexOf("Subject: ") + 9;
        message.insert(idx, tag);
        msg.println(message.toString());

        smtp.closeServer(); // 關閉連線並發送
        return true;
    } catch (Exception e) { /* 錯誤處理與 beep 提示 */ return false; }
}

readLines 靈活擷取郵件區段

private String readLines(String path, String firstLine, String lastLine) {
    StringBuffer buf = new StringBuffer();
    try (BufferedReader in = new BufferedReader(new FileReader(path))) {
        String line; boolean saving = false;
        while ((line = in.readLine()) != null) {
            if (!saving && (firstLine == null || line.startsWith(firstLine))) saving = true;
            if (saving) buf.append(line).append("\n");
            if (lastLine != null && line.startsWith(lastLine)) break;
        }
    } catch (Exception e) { e.printStackTrace(); }
    return buf.toString();
}

郵件檔名格式與編號解析

檔名範例:+OK 38 402fb6da00000098

  • +OK:伺服器回應狀態碼
  • 38:郵件在伺服器上的流水號(1-based,刪除較小編號會導致重新編號)
  • 402fb6da00000098:UIDL 唯一識別碼(同一帳號下不重複)

程式從檔名擷取流水號,格式化為三位數 001~999 插入 Subject。

部署與操作建議

  1. 確認 JDK 1.4.2 以上環境(測試平台為 WinXP)
  2. 建立 Messages、Archives 兩個資料夾
  3. 先執行 java VirPro01a pop3.server user pass 下載郵件
  4. 執行防毒掃描清理 Messages 資料夾
  5. 再執行 java VirPro01b pop3.server user pass smtp.server smtp.host 轉寄與清理
  6. 定期清理 Archives 避免磁碟滿載

安全性與限制提醒

  • 使用非標準 sun.net.smtp.SmtpClient,生產環境建議改用 JavaMail API
  • POP3 認證採明文傳輸,敏感環境請搭配 SSL/TLS 或 VPN
  • 程式內 DELE 指令預設註解,需徹底測試後方可啟用,防止誤刪未成功轉寄的郵件
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved