⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smtpsession.java

📁 邮件服务器
💻 JAVA
字号:
package com.softeem.mail.smtp;

import java.net.*;
import java.util.*;
import java.io.*;

import com.softeem.mail.Constants;

public class SMTPSession extends Thread {
	private static final String CMD_EHLO = "EHLO";
	private static final String CMD_AUTH = "AUTH";
	private static final String CMD_HELO = "HELO";
	private static final String CMD_MAIL = "MAIL FROM:";
	private static final String CMD_RCPT = "RCPT TO:";
	private static final String CMD_DATA = "DATA";
	private static final String CMD_DOT = ".";
	private static final String CMD_QUIT = "QUIT";
	private static final String PATH = "f:/mail/";
	private static Properties propUsername = new Properties();// 用来加载用户属性文件
	private static Properties propDns = new Properties();// 用来加载域名属性文件
	private int state; // 状态码,判断SMTP命令的执行顺序
	private int state2;// 状态码,判断ESMTP命令的执行顺序
	int state3;//判断是用的helo还是ehlo
	private Socket socket;// 连接客户端
	private BufferedReader br;// 读网络流
	private PrintWriter pw;// 写网络流
	private File receiveBox;// 收件箱路径
	private File sendBox;// 发件箱路径
	private File mailFromPath;// 所收邮件的路径
	private File mailToPath;// 所发邮件的路径
	private File tempFile;// 临时保存收发邮件
	private boolean flag;// 判断用户是否存在
	private boolean flag2;// 判断密码是否正确
	private String userName;// 用户名
	private String sendName;// 发件人
	private String receiveName;// 收件人
	private String[] receiveAddress = new String[50];
	private List<String> userList = new ArrayList<String>();

	public SMTPSession(Socket socket) {
		this.socket = socket;
	}

	static {
		InputStream is;
		try {
			is = new FileInputStream(Constants.USER_NAME);
			propUsername.load(is);
			is.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 {
			socket.setSoTimeout(Constants.SOCKET_TIMEOUT);
			br = new BufferedReader(new InputStreamReader(socket
					.getInputStream()));
			pw = new PrintWriter(socket.getOutputStream());
			sendWelcomeMessage();
			while (parseCommand(readCommandLine())) {
				;		
			}
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				br.close();
				pw.close();
				socket.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	private boolean parseCommand(String command) {
		boolean returnValue = true;
		if (command == null) {
			return false;
		}
		String argument = null;
		int spaceIndex = command.lastIndexOf(" ");
		if (spaceIndex > 0) {
			argument = command.substring(spaceIndex + 1);
			command = command.substring(0, spaceIndex);
		}
		System.out.println("进入命令------>" + command + " state-----state2-->" + state+"  "+state2);
		if (command.equalsIgnoreCase(CMD_HELO) && state == 0 && state2 == 0) {
			doHelo(argument);
		} else if (command.equalsIgnoreCase(CMD_EHLO) && state2 == 0
				&& state == 0) {
			doEhlo(argument);
		} else if (command.equalsIgnoreCase(CMD_AUTH) && state2 == 1
				&& state == 0) {
			doAuth();
		} else if (command.equalsIgnoreCase(CMD_MAIL)
				&& (state == 1 || state2 == 1)) {
			doMail(argument);
		} else if (command.equalsIgnoreCase(CMD_RCPT)
				&& (state >= 2 || state2 >= 2)) {
			doRcpt(argument);
		} else if (command.equalsIgnoreCase(CMD_DATA)
				&& (state >= 3 || state2 >= 3)) {
			doData();
		} else if (command.equalsIgnoreCase(CMD_QUIT)) {
			doQuit();
			returnValue = false;
		} else {
			writeMessage("550 命令输入错误,请重新输入!");
		}
		return returnValue;
	}

	private void doQuit() {
		if(mailFromPath!=null) mailFromPath.delete();
		writeMessage("221 bye-bye");
	}

	private void doData() {
		writeMessage("354 请输入邮件内容!");
		try {
			mailFromPath = new File(sendBox, String.valueOf(System
					.currentTimeMillis())
					+ ".txt");
			mailFromPath.createNewFile();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		tempFile = new File(PATH + "/file.txt");
		try {
			PrintStream temp = new PrintStream(new FileOutputStream(tempFile));
			PrintStream ps1 = new PrintStream(
					new FileOutputStream(mailFromPath));
			String line2 = null;
			while ((line2 = br.readLine()) != null) {
				if (line2.equals(CMD_DOT)) {
					break;
				}
				temp.println(line2);
				temp.flush();
				ps1.println(line2);
				ps1.flush();
			}
			temp.close();
			ps1.close();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		for (int i = 0; i < userList.size(); i++) {
			receiveAddress[i] = userList.get(i);
			System.out.println(receiveAddress[i]);
			if (receiveAddress[0].endsWith("@hdjmail.com>")) {
				System.out.println("本地用户,直接发送!");
				receiveName = receiveAddress[i].substring(receiveAddress[i]
						.indexOf("<") + 1, receiveAddress[i].lastIndexOf("@"));
				if (propUsername.containsKey(receiveName)) {
					receiveBox = new File(PATH + receiveName + "/" + "receive");
					System.out.println("收件人的收件箱:"
							+ receiveBox.getAbsolutePath());
					mailToPath = new File(receiveBox, String.valueOf(System
							.currentTimeMillis())
							+ ".txt");
					try {
						mailToPath.createNewFile();
					} catch (IOException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
					writeMessage("250 OK 本地发送!");
					System.out.println("本地发送");
					try {
						BufferedReader brFile = new BufferedReader(
								new InputStreamReader(new FileInputStream(
										tempFile)));
						PrintStream ps2 = new PrintStream(new FileOutputStream(
								mailToPath));
						String line = null;
						while ((line = brFile.readLine()) != null) {
							if (line.equals(CMD_DOT)) {
								writeMessage("250 ok");
								break;
							}
							ps2.println(line);
							ps2.flush();
						}
						ps2.close();
						brFile.close();
					} catch (FileNotFoundException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					state2++;
				} else {
					writeMessage("550 没有您输入的收件人,请您重新选择收件人邮箱!");
				}
			} else {writeMessage("550 SORRY!本服务器不支持转发!");}
		}
	}

	private void doRcpt(String receiveAddress) {
		if (receiveAddress.trim().startsWith("<")
				&& receiveAddress.trim().endsWith(".com>")) {
			userList.add(receiveAddress);
			if(state3==1) state2++;
			if(state3==2) state++;
			writeMessage("250 OK !");
		} else {
			writeMessage("550 输入的邮箱格式错误,请按正确的格式输入:以'<'开头,以'.com>'结尾");
		}
	}

	private void doMail(String sendAddress) {
		System.out.println("go to mail conmend" );
		if (sendAddress.trim().startsWith("<")
				&& sendAddress.trim().endsWith("@hdjmail.com>")) {
			writeMessage("250 OK");
			sendName = sendAddress.substring(sendAddress.lastIndexOf("<") + 1,
					sendAddress.lastIndexOf("@"));
			sendBox = new File(PATH + sendName + "/" + "send/");
			System.out.println("发件人发件箱:" + sendBox.getAbsolutePath());
			if(state3==1) state2++;
			if(state3==2) state++;
			
		} else {
			writeMessage("550  输入的邮箱格式错误,请按正确的格式输入:以'<'开头,以'@hdjmail.com>'结尾");
		}
	}

	private boolean doPass(String password) {
		flag2 = false;
		String str2 = new String(Base645.decode(password));
		System.out.println(str2);
		if (str2.equals(propUsername.getProperty(userName))) {
			writeMessage("235 ok, authentication successfully!");
			flag2 = true;
		} else {
			writeMessage("535 authentication failed");
		}
		return flag2;

	}

	private boolean doUser(String username) {
		flag = false;
		String str = new String(Base645.decode(username.trim()));
		System.out.println(str);
		if (propUsername.containsKey(str)) {
			userName = username.trim();
			flag = true;
		} else {
			writeMessage("550 用户名不存在,请重新输入");
		}
		return flag;
	}

	private void doAuth() {
		writeMessage("334 用户名验证");
		try {
			String str = br.readLine();
			System.out.println(str);
			if (doUser(str)) {
				writeMessage("334 密码验证");
				String str2 = br.readLine();
				System.out.println(str);
				doPass(str2);
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private void doEhlo(String argument) {
		StringBuffer responseBuffer = new StringBuffer();
		if (argument == null) {
			responseBuffer.append("501 Domain address required: ").append(
					CMD_EHLO);
		} else {
			responseBuffer.append("250 Welcome ").append(argument).append(" (")
					.append(socket.getRemoteSocketAddress()).append(")")
					.append(" ").append("准备身份验证.....");
			state2++;
			state3=1;
		}
		writeMessage(responseBuffer.toString());
	}

	private void doHelo(String argument) {
		StringBuffer responseBuffer = new StringBuffer();
		if (argument == null) {
			responseBuffer.append("501 Domain address required: ").append(
					CMD_HELO);
		} else {
			responseBuffer.append("250 Welcome ").append(argument).append(" (")
					.append(socket.getRemoteSocketAddress()).append(")");
			state++;
			state3=2;
		}
		writeMessage(responseBuffer.toString());
	}

	private void writeMessage(String message) {
		pw.println(message);
		pw.flush();
	}

	final String readCommandLine() throws IOException {
		for (;;) {
			String commandLine = br.readLine();
			if (commandLine != null) {
				commandLine = commandLine.trim();
			}
			return commandLine;
		}
	}

	public boolean sendWelcomeMessage() {
		StringBuffer sb = new StringBuffer();
		try {
			sb.append(Constants.RESPONSE_CONN_SUCC).append(" ").append(
					InetAddress.getLocalHost()).append(" ").append("(").append(
					Constants.VERSION_MAILSERVER).append(")").append(" ")
					.append(Constants.SERVER_NAME);
		} catch (UnknownHostException e) {
			e.printStackTrace();
		}
		writeMessage(sb.toString());
		return true;
	}

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -