package com.hhb.mail;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
public class MailSever {
private String smptSever = "smtp.126.com";
private int port = 25;
private static String username;
private static String password;
private static String to=null;
public static void main(String[] args) throws Exception {
if (args.length < 3) {
throw new Exception("请输入你的用户名和密码和接收人! "+
"java MailSever username password to");
}
username = args[0];
password = args[1];
to=args[2];
Message msg=new Message(username, to, "Socket测试","用套接字发送邮件!");
new MailSever().sendMail(msg);
}
public BufferedReader getReader(Socket socket) throws IOException {
InputStream in = socket.getInputStream();
return new BufferedReader(new InputStreamReader(in));
}
public PrintWriter getWriter(Socket socket) throws IOException {
OutputStream outputStream = socket.getOutputStream();
return new PrintWriter(new OutputStreamWriter(outputStream), true);
}
public void sendMail(Message msg) {
Socket socket = null;
try {
// 连接到主机服务器
socket = new Socket(smptSever, port);
BufferedReader br = getReader(socket);
PrintWriter pw = getWriter(socket);
// 获得客户的主机名
String localhost = InetAddress.getLocalHost().getHostName();
// 对用户名和密码进行Base64编码
String _username = new sun.misc.BASE64Encoder().encode(username
.getBytes());
String _password = new sun.misc.BASE64Encoder().encode(password
.getBytes());
//接收服务器的响应数据
sendAndReceive(null, br, pw);
sendAndReceive("HELO " + localhost, br, pw);
sendAndReceive("AUTH LOGIN", br, pw);//服务器认证
sendAndReceive(_username, br, pw);//用户名
sendAndReceive(_password, br, pw);//口令
sendAndReceive("MAIL FROM: <" + msg.from+">", br, pw);
sendAndReceive("RCPT TO: <" + msg.to+">", br, pw);
sendAndReceive("DATA", br, pw);
pw.println("SUBJECT:"+msg.subject+"\r\n");//邮件主题
//发送邮件内容
pw.println(msg.data+":源代码:\r\n");
BufferedReader reader =new BufferedReader(new
InputStreamReader(new FileInputStream(
new File("F:/工作空间/base_workspace/lesson1/" +
"src2/com/hhb/mail/MailSever.java"))));
String line=null;
while((line=reader.readLine())!=null)
{
pw.println(line);
};
System.out.println("Client>" + msg.data);
sendAndReceive(".", br, pw);//邮件发送完毕
sendAndReceive("QUIT", br, pw);//结束通信
} catch (Exception e) {
e.printStackTrace();
} finally {
if (socket != null) {
try {
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
private void sendAndReceive(String str, BufferedReader br, PrintWriter pw)
throws IOException {
if (str != null) {
System.out.println("Client>" + str);
pw.println(str);
}
String response;
if ((response = br.readLine()) != null) {
System.out.println("Sever>" + response);
}
}
}
class Message {
String from;
String to;
String subject;
String data;
public Message(String from, String to, String subject,
String data) {
this.from = from;
this.to = to;
this.subject = subject;
this.data = data;
}
}
介绍smtp命令和ESMTP过程
什么是 SMTP
SMTP (Simple Mail Transfer Protocol) : 电子邮件从客户机传输到服务器或从某一个服务器传输到另一个服务器使用的传输协议。 SMTP 是请求/响应协议,命令和响应都是基于 ASCII 文本,并以 CR 和 LF 符结束。响应包括一个表示返回状态的三位数字代码。SMTP 在 TCP 协议 25 端口监听连接请求。
什么是 ESMTP
ESMTP (Extended SMTP),顾名思义,扩展 SMTP 就是对标准 SMTP 协议进行的扩展。它与 SMTP 服务的区别仅仅是,使用 SMTP 发信不需要验证用户帐户,而用 ESMTP 发信时, 服务器会要求用户提供用户名和密码以便验证身份。验证之后的邮件发送过程与 SMTP 方式没有两样。
SMTP 命令
SMTP 命令包括:
HELO 向服务器标识用户身份。发送者能欺骗,说谎,但一般情况下服务器都能检测到。
EHLO 向服务器标识用户身份。发送者能欺骗,说谎,但一般情况下服务器都能检测到。
MAIL FROM 命令中指定的地址是发件人地址
RCPT TO 标识单个的邮件接收人;可有多个 RCPT TO;常在 MAIL 命令后面。
DATA 在单个或多个 RCPT 命令后,表示所有的邮件接收人已标识,并初始化数据传输,以 CRLF.CRLF 结束
VRFY 用于验证指定的用户/邮箱是否存在;由于安全方面的原因,服务器常禁止此命令
EXPN 验证给定的邮箱列表是否存在,扩充邮箱列表,也常被禁用
HELP 查询服务器支持什么命令
NOOP 无操作,服务器应响应 OK
RSET 重置会话,当前传输被取消
QUIT 结束会话
连接 Winmail Server 使用 SMTP 命令发送邮件
例如:安装 Winmail 的邮件服务器IP是1Array2.168.0.1 (蓝色字体内容由客户端输入,红色字体内容是服务返回的)
telnet 1Array2.168.0.1 25 --------------------------------------- 使用 telnet 命令连接服务器 25 端口
Trying 1Array2.168.0.1... --------------------------------------- 正在连接服务器 25 端口
Connected to 1Array2.168.0.1. ----------------------------------- 连接服务器 25 端口成功
220 Winmail Mail Server ESMTP ready ------------------------- 显示服务器的标识名称 (Winmail 管理工具->高级设置->系统参数->基本参数中可更改)
helo cnu.com ------------------------------------------------ 向服务器标识用户身份,发信不要认证,跳过下面几步直接发送 mail from 命令
250 Winmail Mail Server
ehlo cnu.com ------------------------------------------------ ESMTP 命令,发信需要认证。
250-Winmail Mail Server
250-PIPELINING
250-AUTH=LOGIN PLAIN
250-AUTH LOGIN PLAIN
250-SIZE 20480000
250 8BITMIME
auth login ------------------------------------------------- 进行用户身份认证
334 VXNlcm5hbWU6
Y2ArrayzdGFAYW1heGl0Lm5ldA== ----------------------------------- BASE64 加密后的用户名
334 UGFzc3dvcmQ6
MTk4MjIxNA== ----------------------------------------------- BASE64 加密后的密码
235 auth successfully -------------------------------------- 身份认证成功
(535 auth failure ------------------------------------------ 身份认证失败)
发到本系统中域名下的账户可跳过身份认证。
mail from: <test1@domain.com> ------------------------------ mail from 地址 test1@domain.com
250 ok ----------------------------------------------------- 命令执行成功
rcpt to: <test2@domain.com> -------------------------------- 递送给地址 test2@domain.com
250 ok ----------------------------------------------------- 命令执行成功
data ------------------------------------------------------- 数据传输初始化
354 go ahead ----------------------------------------------- 开始传输数据
From: test1@domain.com
To: test2@domain.com
Date: Mon, 25 Oct 2004 14:24:27 +0800
Subject: test mail
Hi, test2
This is a test mail, you don’t reply it.
.
------------------------------------------------------------ 数据内容,包括BASE64加密后的邮件内容, 以 CRLF.CRLF 结束数据传输
250 ok message accepted for delivery ----------------------- 命令执行成功
quit ------------------------------------------------------- 结束会话
221 Winmail Mail Server
Connection closed by foreign host .------------------------- 断开连接
以上文字转载自 http://www.sudu.cn/info/index.php?op=article&id=279800