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

手把手教你用 Java 實現 SMTP 郵件發送服務器

     編輯:Java 程式設計入門

郵件協議速覽

協議全稱預設埠用途
SMTPSimple Mail Transfer Protocol25發送/轉發郵件
POP3Post Office Protocol v3110接收/下載郵件(存轉模式)
IMAPInternet Message Access Protocol143接收/同步郵件(支援多裝置、僅下載標題)

本文專注 SMTP 發送實現。

SMTP 核心命令(發一封信只需 5 條)

HELO           // 握手,宣告發送方域名
MAIL FROM:     // 發件人
RCPT TO:    // 收件人(可多次)
DATA                   // 進入資料模式
...郵件頭與內容...
.                      // 單獨一行點號結束
QUIT                   // 斷開連線

架構設計:GUI 前端 + SmtpMail 通訊核心

1. 視窗元件佈局

  • 頂部:SMTP 伺服器、收件人、寄件人、主題、附件選擇
  • 中部:郵件內容多行文字區
  • 底部:發送、離開按鈕
  • 啟動時置中顯示:setLocation((screenW - frameW)/2, (screenH - frameH)/2)

2. 事件處理

// 瀏覽附件
cmdBrowse.addActionListener(e -> {
    FileDialog fd = new FileDialog(this, "選擇附件", FileDialog.LOAD);
    fd.setVisible(true);
    lblFile.setText(fd.getDirectory() + fd.getFile());
});

// 發送郵件
cmdSend.addActionListener(e -> {
    mailSender.setFrom(txtFrom.getText().trim());
    mailSender.setTo(txtTo.getText().trim());
    mailSender.addHeader("Subject", txtSubject.getText().trim());
    mailSender.addData(txtMail.getText());
    if (!lblFile.getText().trim().isEmpty())
        mailSender.addAttachment(lblFile.getText().trim());
    mailSender.open(txtServer.getText().trim(), 25);
    mailSender.transmit();
    mailSender.close();
});

// 離開
cmdExit.addActionListener(e -> System.exit(0));
addWindowListener(new WindowAdapter() {
    public void windowClosing(WindowEvent e) { System.exit(0); }
});

核心類:SmtpMail 實現細節

建立連線

public int open(String server, int port) {
    try {
        mailSocket = new Socket(server, port);
        send = new PrintWriter(mailSocket.getOutputStream(), true);
        recv = new BufferedReader(new InputStreamReader(mailSocket.getInputStream()));
        String resp = recv.readLine();
        if (resp.charAt(0) == '4' || resp.charAt(0) == '5') return 0; // 錯誤回應
        return 1;
    } catch (Exception e) { return 0; }
}

發送命令並檢查回應

private int sendString(String cmd) {
    try {
        send.println(cmd);
        String resp = recv.readLine();
        if (resp.length() == 0) return 0;
        char c = resp.charAt(0);
        return (c == '4' || c == '5') ? 0 : 1; // 4xx/5xx 為錯誤
    } catch (Exception e) { return 0; }
}

完整發送流程

public int transmit() {
    // HELO
    if (!domain.isEmpty() && sendString("HELO " + domain) != 1) return 0;
    // MAIL FROM
    if (!from.isEmpty() && sendString("MAIL FROM:" + from) != 1) return 0;
    // RCPT TO
    if (!to.isEmpty() && sendString("RCPT TO:" + to) != 1) return 0;
    // DATA
    if (sendString("DATA") != 1) return 0;
    // 郵件頭
    for (int i = 0; i < headers.size(); i += 2)
        send.println(headers.get(i) + ": " + headers.get(i+1));
    // 自動補 Date
    if (!headers.contains("Date"))
        send.println("Date: " + new Date());
    send.println(); // 空行分隔頭/體
    // 郵件體
    for (String line : body) send.println(line);
    // 結束標記
    if (sendString(".") != 1) return 0;
    return 1;
}

關閉連線

public int close() {
    try {
        sendString("QUIT");
        mailSocket.close();
        return 1;
    } catch (Exception e) { return 0; }
}

完整原始碼結構

// mailSendFrame.java - GUI 主程式
// smtpMail.java    - SMTP 通訊核心
//   欄位:from, to, domain, headers(Vector), body(Vector), attachments(Vector)
//   方法:open/transmit/close/sendString + 郵件組裝輔助方法

擴充方向

  • 認證支援:實作 AUTH LOGIN / AUTH PLAIN(BASE64 編碼帳密)
  • SSL/TLS:使用 SSLSocketFactory 連接 465/587 埠
  • MIME 多部分:支援 HTML 內容、內嵌圖片、多附件(Base64 編碼)
  • 異步佇列:生產者-消費者模式削峰填谷
  • 彈性重試:指數退避、死信佇列

總結

透過 Socket 直連 SMTP 伺服器、按協議發送文本命令、解析數字回應碼,即可實現基礎郵件發送。雖然生產環境建議使用 JavaMail、Apache Commons Email 等成熟庫,但親手實作 SMTP 流程能深度理解郵件傳遞本質,為排查發送失敗、實作客製化郵件系統打下堅實基礎。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved