You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Demo1/src/RealEmailSender.java

177 lines
6.9 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import java.io.*;
import java.net.*;
import java.util.Base64;
import javax.net.ssl.*;
/**
* 真实的邮件发送器
* 使用原生Java实现SMTP协议发送邮件
*/
public class RealEmailSender {
private static final String SMTP_HOST = "smtp.qq.com";
private static final int SMTP_PORT = 587;
/**
* 发送邮件
*/
public static boolean sendEmail(String fromEmail, String fromPassword, String toEmail, String subject, String content) {
try {
// 1. 连接到SMTP服务器
Socket socket = new Socket(SMTP_HOST, SMTP_PORT);
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);
// 2. 读取服务器欢迎信息
String response = reader.readLine();
System.out.println("服务器: " + response);
if (!response.startsWith("220")) {
throw new Exception("SMTP服务器连接失败");
}
// 3. 发送EHLO命令
writer.println("EHLO localhost");
response = readMultiLineResponse(reader);
System.out.println("EHLO响应: " + response);
// 4. 启动TLS加密
writer.println("STARTTLS");
response = reader.readLine();
System.out.println("STARTTLS响应: " + response);
if (!response.startsWith("220")) {
throw new Exception("启动TLS失败");
}
// 5. 升级到SSL连接
SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket sslSocket = (SSLSocket) factory.createSocket(socket, SMTP_HOST, SMTP_PORT, true);
sslSocket.startHandshake();
// 6. 重新创建读写器
reader = new BufferedReader(new InputStreamReader(sslSocket.getInputStream()));
writer = new PrintWriter(sslSocket.getOutputStream(), true);
// 7. 重新发送EHLO
writer.println("EHLO localhost");
response = readMultiLineResponse(reader);
System.out.println("SSL EHLO响应: " + response);
// 8. 认证
writer.println("AUTH LOGIN");
response = reader.readLine();
System.out.println("AUTH响应: " + response);
if (!response.startsWith("334")) {
throw new Exception("认证失败");
}
// 9. 发送用户名Base64编码
String encodedUsername = Base64.getEncoder().encodeToString(fromEmail.getBytes());
writer.println(encodedUsername);
response = reader.readLine();
System.out.println("用户名响应: " + response);
if (!response.startsWith("334")) {
throw new Exception("用户名认证失败");
}
// 10. 发送密码Base64编码
String encodedPassword = Base64.getEncoder().encodeToString(fromPassword.getBytes());
writer.println(encodedPassword);
response = reader.readLine();
System.out.println("密码响应: " + response);
if (!response.startsWith("235")) {
throw new Exception("密码认证失败: " + response);
}
// 11. 发送邮件
// MAIL FROM
writer.println("MAIL FROM:<" + fromEmail + ">");
response = reader.readLine();
System.out.println("MAIL FROM响应: " + response);
if (!response.startsWith("250")) {
throw new Exception("MAIL FROM失败");
}
// RCPT TO
writer.println("RCPT TO:<" + toEmail + ">");
response = reader.readLine();
System.out.println("RCPT TO响应: " + response);
if (!response.startsWith("250")) {
throw new Exception("RCPT TO失败");
}
// DATA
writer.println("DATA");
response = reader.readLine();
System.out.println("DATA响应: " + response);
if (!response.startsWith("354")) {
throw new Exception("DATA失败");
}
// 邮件头和内容
writer.println("From: " + fromEmail);
writer.println("To: " + toEmail);
writer.println("Subject: =?UTF-8?B?" + Base64.getEncoder().encodeToString(subject.getBytes("UTF-8")) + "?=");
writer.println("MIME-Version: 1.0");
writer.println("Content-Type: text/plain; charset=UTF-8");
writer.println("Content-Transfer-Encoding: base64");
writer.println("X-Mailer: MathLearningSystem");
writer.println("X-Priority: 1");
writer.println();
writer.println(Base64.getEncoder().encodeToString(content.getBytes("UTF-8")));
writer.println(".");
response = reader.readLine();
System.out.println("邮件发送响应: " + response);
if (!response.startsWith("250")) {
throw new Exception("邮件发送失败");
}
// 12. 退出
writer.println("QUIT");
response = reader.readLine();
System.out.println("QUIT响应: " + response);
// 13. 关闭连接
sslSocket.close();
System.out.println("邮件发送成功!");
return true;
} catch (Exception e) {
System.err.println("邮件发送失败: " + e.getMessage());
e.printStackTrace();
return false;
}
}
/**
* 读取多行响应
*/
private static String readMultiLineResponse(BufferedReader reader) throws IOException {
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
response.append(line).append("\n");
// 如果行不是以'-'结尾,说明是最后一行
if (line.length() >= 4 && line.charAt(3) != '-') {
break;
}
}
return response.toString();
}
/**
* 创建验证码邮件内容
*/
public static String createVerificationEmailContent(String verificationCode) {
return "您好!\n\n" +
"您正在注册数学学习软件,您的验证码是:\n\n" +
"验证码:" + verificationCode + "\n\n" +
"验证码有效期为10分钟请及时使用。\n" +
"如果您没有注册我们的软件,请忽略此邮件。\n\n" +
"祝您学习愉快!\n" +
"数学学习软件团队\n\n" +
"此邮件由系统自动发送,请勿回复。";
}
}