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

Java 實作 SMTP 郵件發送器:從 Socket 到 MIME 完整實戰

     編輯:Java 相關知識

不依賴 JavaMail API,直接基於 Socket 與 SMTP 協議(RFC 5321)手寫郵件發送類。支援 AUTH LOGIN 認證、多收件人、自定義編碼(GB2312/UTF-8)、主旨與純文字內文。適合理解郵件協議細節或無法引入外部庫的環境。

核心流程

  1. 建立 Socket(smtpHost, 25) 連線
  2. 讀取 220 歡迎回應
  3. 發送 HELO hostname,讀 250
  4. 若需認證:AUTH LOGIN → Base64(user) → Base64(pass),各讀 334/235
  5. MAIL FROM:<from>、RCPT TO:<to>(多收件人循環)
  6. DATA 進入資料模式,發送完整 MIME 訊息(Headers + 空行 + Body + \r\n.\r\n)
  7. QUIT 結束會話

關鍵代碼片段

public class SMTPSender {
    private Socket socket;
    private PrintWriter out;
    private BufferedReader in;
    private final String CRLF = "\r\n";

    public boolean send(String subject, String content) {
        try {
            socket = new Socket(smtpServer, 25);
            out = new PrintWriter(socket.getOutputStream());
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

            readResponse("220");
            sendCmd("HELO " + smtpServer);
            readResponse("250");

            if (needAuth) {
                sendCmd("AUTH LOGIN"); readResponse("334");
                sendCmd(Base64.encode(user)); readResponse("334");
                sendCmd(Base64.encode(pass)); readResponse("235");
            }

            sendCmd("MAIL FROM:<" + from + ">"); readResponse("250");
            for (String to : recipients) {
                sendCmd("RCPT TO:<" + to + ">"); readResponse("250");
            }
            sendCmd("DATA"); readResponse("354");

            StringBuilder msg = new StringBuilder();
            msg.append("From: ").append(from).append(CRLF);
            msg.append("To: ").append(String.join(",", recipients)).append(CRLF);
            msg.append("Subject: ").append(subject).append(CRLF);
            msg.append("Content-Type: text/plain; charset=UTF-8").append(CRLF);
            msg.append(CRLF).append(content).append(CRLF).append(".").append(CRLF);
            sendCmd(msg.toString());
            readResponse("250");

            sendCmd("QUIT"); readResponse("221");
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally { closeQuietly(); }
    }

    private void sendCmd(String cmd) { out.print(cmd); out.flush(); }
    private void readResponse(String expect) throws Exception {
        String line = in.readLine();
        if (line == null || !line.startsWith(expect)) throw new Exception("SMTP 錯誤: " + line);
        while (line.startsWith(expect + "-")) line = in.readLine(); // 多行回應
    }
    // Base64 工具類、closeQuietly() 略
}

生產環境建議

  • 改用 JavaMail 或 Spring Boot Mail:支援 SSL/TLS (465/587)、HTML 郵件、附件、連線池、重試機制。
  • SMTP 伺服器多要求 STARTTLS,純 Socket 需自行升級為 SSLSocket。
  • 大量發送請使用專業郵件服務(SendGrid、Amazon SES、Mailgun)並實作佇列與退信處理。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved