直接使用 Socket 連接 SMTP 服務器(默認端口 25),按 SMTP 協議發送命令序列:HELO/EHLO → AUTH LOGIN → Base64 編碼用戶名/密碼 → MAIL FROM → RCPT TO → DATA → 郵件內容 → . → QUIT。
@163/@126/@sina/@qq)選擇對應 SMTP 主機。sun.misc.BASE64Encoder,編譯警告屬正常,因屬內部 API)。DATA 後發送頭部(From/To/Subject),Subject 後必須空一行(\r\n),然後正文,結尾單獨一行 .。\r\n 結束。class E_Mail {
String from, to, subject, content, userName, pwd;
public E_Mail(String from, String to, String subject, String content, String userName, String pwd) {
this.from = from; this.to = to; this.subject = subject; this.content = content;
this.userName = toBASE64(userName); this.pwd = toBASE64(pwd);
}
private String toBASE64(String str) {
return new sun.misc.BASE64Encoder().encode(str.getBytes());
}
}
public class SimpleMailSender {
private String smtpServer; private int port = 25;
private Socket socket; private BufferedReader br; private PrintWriter pw;
private void initServer(String from) { /* 根據後綴設置 smtpServer */ }
public void sendEmail(E_Mail email) {
try {
initServer(email.from);
socket = new Socket(smtpServer, port);
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
pw = new PrintWriter(socket.getOutputStream(), true);
sendReceive(null); // 接收歡迎信息
sendReceive("ehlo hao");
sendReceive("auth login");
sendReceive(email.userName);
sendReceive(email.pwd);
sendReceive("mail from:<" + email.from + ">");
sendReceive("rcpt to:<" + email.to + ">");
sendReceive("data");
pw.println("from:" + email.from);
pw.println("to:" + email.to);
pw.println("subject:" + email.subject + "\r\n"); // 關鍵空行
pw.println(email.content);
sendReceive("."); // 結束數據
sendReceive("quit");
} catch (IOException e) { e.printStackTrace(); }
finally { closeQuietly(socket); }
}
private void sendReceive(String cmd) throws IOException {
if (cmd != null) { pw.print(cmd + "\r\n"); pw.flush(); System.out.println(">> " + cmd); }
char[] buf = new char[1024];
br.read(buf);
System.out.println(new String(buf).trim());
}
// getReader/getWriter/closeQuietly 略
}
class MailSenderGUI extends JFrame implements ActionListener {
// 組件:發件人、用戶名、密碼、收件人、主題、正文、發送/重置按鈕
// 佈局:BorderLayout 北部表單、中部正文區、南部按鈕
// 事件:發送 → 組裝 E_Mail → 調用 SimpleMailSender.sendEmail()
// 重置 → 清空所有輸入框
}
sendEmail 中命令序列有重複,可提取為命令數組循環發送。手寫 SMTP 客戶端能深入理解郵件協議細節,適合教學與輕量級無依賴場景。生產環境強烈建議使用成熟庫(JavaMail、Simple Java Mail),支持 SSL/TLS、MIME、附件、異步發送等企業級特性。