📄 smtpservice.java
字号:
package com.softeem.myMail.smtp;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Properties;
public class SMTPService implements Runnable {
private Socket socket;
private BufferedReader br;
private BufferedWriter bf;
private BufferedWriter bw;
private OutputStream bp;
private String scr;
private Date date;
Properties prop = new Properties();
public SMTPService(Socket socket) {
this.socket = socket;
}
public void init() {
try {
// 解析属性文件得到对应的值
InputStream in = new FileInputStream("config.properties");
prop.load(in);
in.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void run() {
try {
br = new BufferedReader(new InputStreamReader(socket
.getInputStream()));
bw = new BufferedWriter(new OutputStreamWriter(socket
.getOutputStream()));
bp = new FileOutputStream(new File("config.properties"), true);
sendWelcomeMessage();
while (prastCommand(br.readLine())) {
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
bw.close();
br.close();
bf.close();
bp.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// 欢迎信息
private void sendWelcomeMessage() {
StringBuffer welcomMessage = new StringBuffer();
welcomMessage.append("220").append(" ").append(
socket.getInetAddress().getHostAddress()).append(" ").append(
"mail server v1.0").append(" ").append("for java23");
writerMessage(welcomMessage.toString());
}
/*
* HELO java23
* MAIL FROM:<frank@localhost.com>
* RCPT TO:<to@localhost.com>
* DATA QUIT 解析服务器的指令
*/
private boolean prastCommand(String command) {
Boolean flag = true;
// 从发送的消息中获得空格的位置
int spaceIndex = command.indexOf(" ");
String argument = null;
// 这种方式解决没输空格的错误
if (spaceIndex > 0) {
// 获得具体的消息
argument = command.substring(spaceIndex + 1);
// 获得指令
command = command.substring(0, spaceIndex);
}
if (command.equalsIgnoreCase("HELO")) {
doHELO(argument);
} else if (command.equalsIgnoreCase("MAIL")) {
doMAIL(argument);
} else if (command.equalsIgnoreCase("RCPT")) {
doRCPT(argument);
} else if (command.equalsIgnoreCase("DATA")) {
doDATA(argument);
} else if (command.equalsIgnoreCase("QUIT")) {
doQUIT(argument);
return flag = false;
} else {
writerMessage("501 Syntax error in MAIL command");
}
return flag;
}
private void doHELO(String argument) {
StringBuffer responseBuff = new StringBuffer();
if (argument.length() == 0) {
responseBuff.append("250").append(" ").append("null").append(" ")
.append("OK");
} else
responseBuff.append("250").append(" ").append(argument).append(" ")
.append("OK");
writerMessage(responseBuff.toString());
}
private void doMAIL(String argument) {
init();
StringBuffer responseBuffer = new StringBuffer();
String responseString;
String sender = null;
// 判断消息是否为空和是否输入:号
if ((argument == null) || (argument.indexOf(":") == -1)) {
responseString = "501 Usage: MAIL FROM:<sender>";
writerMessage(responseString);
} else if ((argument != null) && (argument.indexOf(":") > 0)) {
// 获得:号的位置
int colonIndex = argument.indexOf(":");
// 获得:号之前的字段
sender = argument.substring(colonIndex + 1);
argument = argument.substring(0, colonIndex);
// 获得"<",">","@"的位置
int less = sender.indexOf("<");
int max = sender.indexOf(">");
int a = sender.indexOf("@");
// 将所有的字母转换为大写
if (!argument.toUpperCase(Locale.US).equals("FROM")) {
responseString = "501 Usage: MAIL FROM:<sender>";
writerMessage(responseString);
} else if (less == -1 || max == -1 || a == -1) {
responseString = "501 Usage: MAIL FROM:<sender>";
writerMessage(responseString);
} else if (less != -1 && max != -1 && a != -1) {
// 获得名称,类型,域名
String str1 = sender.substring(less, a);
String str2 = sender.substring(a + 1, max);
String str3 = sender.substring(max + 1);
if (str1.length() == 0 || str2.length() == 0
|| str3.length() != 0) {
responseString = "501 Usage: MAIL FROM:<sender>";
writerMessage(responseString);
} else {
// 获得发送者的名字
sender = sender.substring(less + 1, a);
if (prop.getProperty(sender) == null) {
// 创建发送者邮箱
File fSendbox = new File("E:\\mail\\" + sender
+ "\\senderbox");
fSendbox.mkdirs();
File freceive = new File("E:\\mail\\" + sender
+ "\\receivebox");
freceive.mkdirs();
// 在属性文件中存入发件箱的用户名和密码
prop.put(sender, "123");
try {
prop.store(bp, null);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
responseBuffer.append("250 Sender <").append(sender)
.append("> OK");
writerMessage(responseBuffer.toString());
}
}
}
}
private void doRCPT(String argument) {
init();
// 获得当前的时间
date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HH-MM-SS");
String formateDate = sdf.format(date);
StringBuffer responseBuffer = new StringBuffer();
String responseString;
String recipient = null;
if ((argument == null) || (argument.indexOf(":") == -1)) {
responseString = "501 Usage: MAIL FROM:<recipient>";
writerMessage(responseString);
} else if ((argument != null) && (argument.indexOf(":") > 0)) {
// 获得:号的位置
int colonIndex = argument.indexOf(":");
// 获得:号之前的字段
recipient = argument.substring(colonIndex + 1);
argument = argument.substring(0, colonIndex);
// 获得"<",">","@"的位置
int less = recipient.indexOf("<");
int max = recipient.indexOf(">");
int a = recipient.indexOf("@");
// 将所有的字母转换为大写
if (argument == null
|| !argument.toUpperCase(Locale.US).equals("TO")
|| recipient == null) {
responseString = "501 Usage: MAIL FROM:<recipient>";
writerMessage(responseString);
} else if (less == -1 || max == -1 || a == -1) {
responseString = "501 Usage: MAIL FROM:<recipient>";
writerMessage(responseString);
} else if (less != -1 && max != -1 && a != -1) {
// 获得名称,类型,域名
String str1 = recipient.substring(less, a);
String str2 = recipient.substring(a + 1, max);
String str3 = recipient.substring(max + 1);
if (str1.length() == 0 || str2.length() == 0
|| str3.length() != 0) {
responseString = "501 Usage: MAIL FROM:<recipient>";
writerMessage(responseString);
} else {
// 获得接收者的名字
recipient = recipient.substring(less + 1, a);
scr = recipient;
if (prop.getProperty(recipient) == null) {
// 创建接收者邮箱
File fSendbox = new File("E:\\mail\\" + recipient
+ "\\senderbox");
fSendbox.mkdirs();
File freceive = new File("E:\\mail\\" + recipient
+ "\\receivebox");
freceive.mkdirs();
try {
// 在接收者邮箱用时间为名字创建邮件
bf = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(new File("E:\\mail\\"
+ scr + "\\receivebox\\"
+ formateDate + ".txt"))));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 在属性文件中存入收件箱的用户名和密码
prop.put(recipient, "123");
try {
prop.store(bp, null);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
try {
bf = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(new File("E:\\mail\\"
+ scr + "\\receivebox\\"
+ formateDate + ".txt"))));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
responseBuffer.append("250 Recipient <").append(recipient)
.append("> OK");
writerMessage(responseBuffer.toString());
}
}
}
}
private void doDATA(String argument) {
StringBuffer responseBuffer = new StringBuffer();
String responseString = null;
responseString = "354 Ok Send data ending with <CRLF>.<CRLF>";
writerMessage(responseString);
try {
// 获取信息
String str = br.readLine();
// 判断写的信息是否以"."结尾
while (!str.equals(".")) {
writerFile(str);
}
responseBuffer.append("250 OK COMMAND IMPLEMENTS");
writerMessage(responseBuffer.toString());
} catch (IOException e) {
e.printStackTrace();
}
}
private void doQUIT(String argument) {
try {
StringBuffer responseBuff = new StringBuffer();
responseBuff.append("250 coremail");
writerMessage(responseBuff.toString());
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// 将信息写入文件
private void writerFile(String responseBuffer) {
try {
bf.write(responseBuffer);
bf.newLine();
bf.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
private void writerMessage(String massager) {
try {
bw.write(massager);
bw.newLine();
bw.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
// private void writerProperties(String keyValue) {
// try {
// bp.write(keyValue);
// bp.newLine();
// bp.flush();
//
// } catch (IOException e) {
// e.printStackTrace();
// }
//
// }
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -