SMTP(Simple Mail Transfer Protocol)协议用于电子邮件传输。实现SMTP协议主要包含:
- 连接SMTP服务器:默认端口25。
- 鉴权:使用用户名和密码登录,若服务器支持TLS,需要先建立TLS连接。
- 邮件内容构建:根据RFC 5321规范构建邮件内容,包含发件人、收件人、主题、正文等。
- 发送邮件:使用MAIL FROM和RCPT TO命令指定发件人和收件人,使用DATA命令发送邮件内容。
- 断开连接:使用QUIT命令断开SMTP连接。
实现一个简单的SMTP客户端可以如下:
public class SMTPClient {
private Socket socket;
private OutputStream out;
private String server;
private int port = 25;
public SMTPClient(String server, int port) throws IOException {
this.server = server;
this.port = port;
connect();
}
private void connect() throws IOException {
socket = new Socket(server, port);
out = socket.getOutputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String welcomeMsg = in.readLine(); // 220 Welcome message
sendCommand("EHLO localhost"); // 250 Success
sendCommand("STARTTLS"); // 220 Ready to start TLS
startTLS(); // Reconnect with TLS
sendCommand("EHLO localhost"); // 250 Success
sendCommand("AUTH LOGIN"); // 334 Username
sendCommand(Base64.encode("username")); // 334 Password
sendCommand(Base64.encode("password")); // 235 Success
}
private void startTLS() throws IOException {
SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket sslSocket = (SSLSocket) factory.createSocket(socket, server, port, true);
socket = sslSocket;
out = socket.getOutputStream();
}
private void sendCommand(String cmd) throws IOException {
out.write((cmd + "\r\n").getBytes());
String response = socket.getInputStream().readLine();
}
public void sendEmail(String from, String to, String subject, String content) throws IOException {
sendCommand("MAIL FROM: <" + from + ">"); // 250 OK
sendCommand("RCPT TO: <" + to + ">"); // 250 OK
sendCommand("DATA"); // 354 Start mail input; end with <CR><LF>.<CR><LF>
out.write(("Subject: " + subject + "\r\n").getBytes());
out.write(content.getBytes());
sendCommand("\r\n.\r\n"); // 250 OK
sendCommand("QUIT"); // 221 Bye
}
}
我们可以这样使用SMTPClient发送邮件:
SMTPClient client = new SMTPClient("smtp.example.com");
client.sendEmail("from@example.com", "to@example.com", "Subject", "Content");