JAVA实现简易的邮件客户端程序

/**
 * 简易的邮件客户端程序,后期将逐步完善提供友好UI
 * 测试发现不支持Gmail,Gmail SMTP采用了TSL/SSL协议
 * 已知JavaMail可实现SSL协议。。。
 */
package mail;

/**
 * @author Daniel Cheng
 *
 */
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.StringTokenizer;

public class SMTPClient {

	private boolean debug = true;
	BASE64Encoder encode = new BASE64Encoder();// 自定义BASE64Encoder工具类用于加密字符串

	public static void main(String[] args) throws UnknownHostException,
			IOException {
		MailMessage message = new MailMessage();
		message.setFrom("[email protected]");// 发件人
		message.setTo("[email protected],[email protected],[email protected]");// 多个收件人地址间用逗号隔开
		String server = "smtp.163.com";// SMTP邮件服务器
		message.setSubject("Java Mail Test");// 邮件主题
		message.setContent("你好!这里是系统发出的JAVA MAIL测试,请勿回复。");// 邮件内容
		message.setDataFrom("Sender");// 发件人,在邮件的发件人栏目中显示
		message.setDataTo("Receiver");// 收件人,在邮件的收件人栏目中显示
		message.setUser("[email protected]");// 登陆的邮箱账号
		message.setPassword("********");// 登陆邮箱的密码,建议自己保密好,公开传播会泄密

		SMTPClient smtp = new SMTPClient(server, 25);
		boolean flag;
		flag = smtp.sendMail(message, server);
		if (flag) {
			System.out.println("邮件发送成功!");
		} else {
			System.out.println("邮件发送失败!");
		}
	}

	private Socket socket;

	public SMTPClient(String server, int port) throws UnknownHostException,
			IOException {
		try {
			socket = new Socket(server, 25);
		} catch (SocketException e) {
			System.out.println(e.getMessage());
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			System.out.println("已经建立连接!");
		}

	}

	// 注册到邮件服务器
	public void helo(String server, BufferedReader in, BufferedWriter out)
			throws IOException {
		int result;
		result = getResult(in);
		// 连接上邮件服务后,服务器给出220应答
		if (result != 220) {
			throw new IOException("连接服务器失败");
		}
		result = sendServer("HELO " + server, in, out);
		// HELO命令成功后返回250
		if (result != 250) {
			throw new IOException("注册邮件服务器失败!");
		}
	}

	private int sendServer(String str, BufferedReader in, BufferedWriter out)
			throws IOException {
		out.write(str);
		out.newLine();
		out.flush();
		if (debug) {
			System.out.println("已发送命令:" + str);
		}
		return getResult(in);
	}

	public int getResult(BufferedReader in) {
		String line = "";
		try {
			line = in.readLine();
			if (debug) {
				System.out.println("服务器返回状态:" + line);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		// 从服务器返回消息中读出状态码,将其转换成整数返回
		StringTokenizer st = new StringTokenizer(line, " ");
		return Integer.parseInt(st.nextToken());
	}

	public void authLogin(MailMessage message, BufferedReader in,
			BufferedWriter out) throws IOException {
		int result;
		result = sendServer("AUTH LOGIN", in, out);
		if (result != 334) {
			throw new IOException("用户验证失败!");
		}

		result = sendServer(encode.encode(message.getUser().getBytes()), in,
				out);
		if (result != 334) {
			throw new IOException("错误!");
		}
		result = sendServer(encode.encode(message.getPassword().getBytes()),
				in, out);

		if (result != 235) {
			throw new IOException("验证失败!");
		}
	}

	// 开始发送消息,邮件源地址
	public void mailFrom(String source, BufferedReader in, BufferedWriter out)
			throws IOException {
		int result;
		result = sendServer("MAIL FROM:<" + source + ">", in, out);
		if (result != 250) {
			throw new IOException("指定源地址错误");
		}
	}

	// 设置邮件收件人。多邮件发送用","隔开
	public void rcpt(String touchman, BufferedReader in, BufferedWriter out)
			throws IOException {

		String[] mailList = touchman.split(",");
		if (mailList.length > 1) {
			for (String touch : mailList) {
				connectionServer(touch,in,out);
			}
		}else
			connectionServer(touchman,in,out);

	}

	private void connectionServer(String touch, BufferedReader in, BufferedWriter out)
			throws IOException {
		int result;
		result = sendServer("RCPT TO:<" + touch + ">", in, out);
		if (result != 250) {
			throw new IOException("指定目的地址错误!");
		}
	}

	// 邮件体
	public void data(String from, String to, String subject, String content,
			BufferedReader in, BufferedWriter out) throws IOException {
		int result;
		result = sendServer("DATA", in, out);
		// 输入DATA回车后,若收到354应答后,继续输入邮件内容
		if (result != 354) {
			throw new IOException("不能发送数据");
		}
		out.write("From: " + from);
		out.newLine();
		out.write("To: " + to);
		out.newLine();
		out.write("Subject: " + subject);
		out.newLine();
		out.newLine();
		out.write(content);
		out.newLine();
		// 句号加回车结束邮件内容输入
		result = sendServer(".", in, out);
		System.out.println(result);
		if (result != 250) {
			throw new IOException("发送数据错误");
		}
	}

	// 退出
	public void quit(BufferedReader in, BufferedWriter out) throws IOException {
		int result;
		result = sendServer("QUIT", in, out);
		if (result != 221) {
			throw new IOException("未能正确退出");
		}
	}

	// 发送邮件主程序
	public boolean sendMail(MailMessage message, String server) {
		try {
			BufferedReader in = new BufferedReader(new InputStreamReader(socket
					.getInputStream()));
			BufferedWriter out = new BufferedWriter(new OutputStreamWriter(
					socket.getOutputStream()));
			helo(server, in, out);// HELO命令
			authLogin(message, in, out);// AUTH LOGIN命令
			mailFrom(message.getFrom(), in, out);// MAIL FROM
			rcpt(message.getTo(), in, out);// RCPT
			data(message.getDataFrom(), message.getDataTo(), message
					.getSubject(), message.getContent(), in, out);// DATA
			quit(in, out);// QUIT
		} catch (Exception e) {
			e.printStackTrace();
			return false;

		}
		return true;
	}

}

 

/**
 * 邮件实体POJO类
 */
package mail;

/**
 * @author Daniel Cheng
 *
 */
public class MailMessage {
	private String from;
	private String to;
	private String subject;
	private String content;
	private String dataFrom;
	private String dataTo;
	private String user;
	private String password;
	/**
	 * 
	 */
	public MailMessage() {
		super();
		// TODO Auto-generated constructor stub
	}
	/**
	 * @param from
	 * @param to
	 * @param subject
	 * @param content
	 * @param dataFrom
	 * @param dataTo
	 * @param user
	 * @param password
	 */
	public MailMessage(String from, String to, String subject, String content,
			String dataFrom, String dataTo, String user, String password) {
		super();
		this.from = from;
		this.to = to;
		this.subject = subject;
		this.content = content;
		this.dataFrom = dataFrom;
		this.dataTo = dataTo;
		this.user = user;
		this.password = password;
	}
	public String getFrom() {
		return from;
	}
	public void setFrom(String from) {
		this.from = from;
	}
	public String getTo() {
		return to;
	}
	public void setTo(String to) {
		this.to = to;
	}
	public String getSubject() {
		return subject;
	}
	public void setSubject(String subject) {
		this.subject = subject;
	}
	public String getContent() {
		return content;
	}
	public void setContent(String content) {
		this.content = content;
	}
	public String getDataFrom() {
		return dataFrom;
	}
	public void setDataFrom(String dataFrom) {
		this.dataFrom = dataFrom;
	}
	public String getDataTo() {
		return dataTo;
	}
	public void setDataTo(String dataTo) {
		this.dataTo = dataTo;
	}
	public String getUser() {
		return user;
	}
	public void setUser(String user) {
		this.user = user;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	

}

 

/**
 * BASE64Encoder加密类
 */
package mail;

/**
 * @author Daniel Cheng
 *
 */
public class BASE64Encoder {
	private static char[] codec_table = { 'A', 'B', 'C', 'D', 'E', 'F', 'G',
        'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
        'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
        'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
        'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6',
        '7', '8', '9', '+', '/' };

public BASE64Encoder() {

}

public String encode(byte[] a) {
    int totalBits = a.length * 8;
    int nn = totalBits % 6;
    int curPos = 0;// process bits
    StringBuffer toReturn = new StringBuffer();
    while (curPos < totalBits) {
        int bytePos = curPos / 8;
        switch (curPos % 8) {
        case 0:
            toReturn.append(codec_table[(a[bytePos] & 0xfc) >> 2]);
            break;
        case 2:

            toReturn.append(codec_table[(a[bytePos] & 0x3f)]);
            break;
        case 4:
            if (bytePos == a.length - 1) {
                toReturn
                        .append(codec_table[((a[bytePos] & 0x0f) << 2) & 0x3f]);
            } else {
                int pos = (((a[bytePos] & 0x0f) << 2) | ((a[bytePos + 1] & 0xc0) >> 6)) & 0x3f;
                toReturn.append(codec_table[pos]);
            }
            break;
        case 6:
            if (bytePos == a.length - 1) {
                toReturn
                        .append(codec_table[((a[bytePos] & 0x03) << 4) & 0x3f]);
            } else {
                int pos = (((a[bytePos] & 0x03) << 4) | ((a[bytePos + 1] & 0xf0) >> 4)) & 0x3f;
                toReturn.append(codec_table[pos]);
            }
            break;
        default:
            //never hanppen
            break;
        }
        curPos+=6;
    }
    if(nn==2)
    {
        toReturn.append("==");
    }
    else if(nn==4)
    {
        toReturn.append("=");
    }
    return toReturn.toString();

}

}
 

你可能感兴趣的:(java,.net,UI,socket,Gmail)