java socket 实现 SMTP 协议 发送邮件
文章分类:Java 编程
package ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
/**
* 通过 socket 向 smtp 协议服务器发送邮件
* @author fuyanqing
*
*/
public class SocketMail {
String mailServer;
String from;
String to;
String content;
String lineFeet = "\r\n";
private int port = 25;
Socket client;
BufferedReader in;
DataOutputStream os;
public String getContent() {
return content;
}
public void setContent(String content) {
= content;
}
public String getMailServer() {
return mailServer;
}
public void setMailServer(String mailServer) {
= mailServer;
}
public String getFrom() {
return from;
}
public void setFrom(String from) {
= from;
}
public String getTo() {
return to;
}
public void setTo(String to) {
= to;
}
/**
* 初始化连接
* @return
*/
private boolean init(){
boolean boo = true;
if(mailServer==null || "".equals(mailServer)){
return false;
}
try {
client = new Socket(mailServer,port);
in = new BufferedReader(new InputStreamReader(()));
os = new DataOutputStream(());
String isConnect = response();
if(("220")){
}else{
("建立连接失败:"+isConnect);
boo = false;
}
} catch (UnknownHostException e) {
("建立连接失败!");
();
boo = false;
} catch (IOException e) {
("读取流失败!");
();
boo = false;
}
return boo;
}
/**
* 发送 smtp 指令
* 并返回服务器响应信息
*/
private String sendCommand(String msg){
String result = null;
try {
(msg);
();
result = response();
} catch (IOException e) {
();
}
return result;
}
/**
* 读取服务器端响应信息
* @return
*/
private String response(){
String result = null;
try {
result = ();
} catch (IOException e) {
();
}
return result;
}
/**
* 关闭
*/
private void close(){
try {
();
();
();
} catch (IOException e) {
();
}
}
/**
* 发送邮件
* @return
*/
public boolean sendMail(){
//初始化
if(client==null){
if(init()){
}else{
return false;
}
}
//判断 from,to
if(from==null || () || to == null || ()){
return false;
}
//进行握手
String result = sendCommand("HELO "+mailServer+lineFeet);
if(isStartWith(result,"250")){
}else{
("握手失败:"+result);
return false;
}
//验证发信人信息
String auth = sendCommand("AUTH LOGIN"+lineFeet);
if(isStartWith(auth,"334")){
}else{
return false;
}
String user = sendCommand(new String(("*****".getBytes()))+lineFeet);
if(isStartWith(user,"334")){
}else{
return false;
}
String pass = sendCommand(new String(("*****".getBytes()))+lineFeet);
if(isStartWith(pass,"235")){
}else{
return false;
}
//发送指令
String f = sendCommand("Mail From:<"+from+">"+lineFeet);
if(isStartWith(f,"250")){
}else{
return false;
}
String toStr = sendCommand("RCPT TO:<"+to+">"+lineFeet);
if(isStartWith(toStr,"250")){
}else{
return false;
}
String data = sendCommand("DATA"+lineFeet);
if(isStartWith(data,"354")){
}else{
return false;
}
StringBuilder sb = new StringBuilder();
("From:<"+from+">"+lineFeet);
("To:<"+to+">"+lineFeet);
("Subject:test"+lineFeet);
("Date:2010/10/27 17:30"+lineFeet);
("Content-Type:text/plain;charset=\"GB2312\""+lineFeet);
(lineFeet);
(content);
(lineFeet+"."+lineFeet);
String conStr = sendCommand(());
if(isStartWith(conStr,"250")){
}else{
return false;
}
//quit
String quit = sendCommand("QUIT"+lineFeet);
if(isStartWith(quit,"221")){
}else{
return false;
}
close();
return true;
}
private boolean isStartWith(String res,String with){
return (with);
}
public static void main(String[] args){
SocketMail mail = new SocketMail();
("");
("*****@");
("*****@");
("hello,this is a test mail!");
boolean boo = ();
if(boo)
("邮件发送成功!");
else{
("邮件发送失败!");
}
}
}
···························································································
SMTP 的连接和收发过程:
a.建立 TCP 连接。
b.客户端发送 HELO 命令以标识发件人自己的身份,然后客户端发送 MAIL 命令
服务器端正希望以 OK 作为响应,表明准备接收。
c.客户端发送 RCPT 命令,以标识该电子邮件的计划接收人,可以有多个 RCPT
行
d.协商结束,发送邮件,用命令 DATA 发送
e.以.表示结束输入内容一起发送出去
f.结束此次发送,用 QUIT 命令退出。
SMTP 的基本命令集:
HELO 向服务器标识用户身份
MAIL 初始化邮件传输 mail from: <xxx>
RCPT 标识单个的邮件接收人;常在 MAIL 命令后面可有多个 rcpt to: <xxx>
DATA 在单个或多个 RCPT 命令后,表示所有的邮件接收人已标识,初始
化数据传输,以.结束。
NOOP 无操作,服务器应响应 OK
RSET 重置会话,当前传输被取消
QUIT 结束会话
POP3 简介:
在 POP3 协议中有三种状态,认可状态,处理状态,和更新状态。当客户机与服
务器建立联系时,一旦客户机提供了自己身份并成功确认,即由认可状态转入处
理状态,在完成相应的操作后客户机发出 quit 命令,则进入更新状态,更新之后
最后重返认可状态。
POP3 基本命令集:
USER username
PASS password
STAT 请求服务器发回关于邮箱的统计资料,如邮件总数和总字节数
LIST 返回邮件数量和每个邮件的大小
RETR [Msg#] 返回由参数标识的邮件的全部文本
DELE [Msg#] 服务器将由参数标识的邮件标记为删除,由 quit 命令执行
RSET 服务器将重置所有标记为删除的邮件,用于撤消 DELE 命令
NOOP 服务器返回一个肯定的响应
QUIT 更新
class POP3Demo {
private static String POP3Server = "";
private static String USERNAME = "username";//实际应用中改成真实的用户名
private static String PASSWORD = "password";//实际应用中改成真实的密码
public static void main(String[] args) {
int POP3Port = 110;
Socket client = null;
try {
// 向 POP3 服务程序建立一个套接字连接。
client = new Socket(, POP3Port);
// 创建一个 BufferedReader 对象,以便从套接字读取输出。
InputStream is = ();
BufferedReader sockin = new BufferedReader(new InputStreamReader(is));
// 创建一个 PrintWriter 对象,以便向套接字写入内容。
OutputStream os = ();
PrintWriter sockout = new PrintWriter(os, true);
// 显示同 SMTP 服务程序的握手过程。
("S:" + ());
("user " + );
("S:" + ());
("pass " + );
("S:" + ());
("stat");
String temp[] = ().split(" ");
int count = (temp[1]);//得到信箱中共有多少封邮件
for (int i = 1; i < count + 1; i++) {//依次打印出邮件的内容
("retr " + i);
("以下为第" + i + "封邮件的内容");
while (true) {
String reply = ();
(reply);
if (().equals(".")) {
break;
}
}
} </xxx></xxx>
} catch (IOException e) {
(());
} finally {
try {
if (client != null) {
();
}
} catch (IOException e) {}
}
}
}
class SMTPDemo {
//以下三项请在使用时改成真实的信箱地址
//并且注意,SMTPServer 和 receiver 必须是同一个服务器
private static String sender = "sender";
private static String receiver = "receiver";
private static String SMTPServer = "smtpserver";
public static void main(String[] args) {
int SMTPPort = 25;
Socket client = null;
try {
// 向 SMTP 服务程序建立一个套接字连接。
client = new Socket(, SMTPPort);
// 创建一个 BufferedReader 对象,以便从套接字读取输出。
InputStream is = ();
BufferedReader sockin = new BufferedReader(new InputStreamReader(is));
// 创建一个 PrintWriter 对象,以便向套接字写入内容。
OutputStream os = ();
PrintWriter sockout = new PrintWriter(os, true);
// 显示同 SMTP 服务程序的握手过程。
("S:" + ());
("helo");
("S:" + ());
("mail from: " + "<" + + ">");
("S:" + ());
("rcpt to: " + "<" + + ">");
("S:" + ());
("data");
//发送邮件标题
("subject: 你好");
//发送邮件内容
("ni hao");
("wo shi li jian");
//此处的.为特殊标记,表示邮件结束
(".");
("rset");
("quit");
} catch (IOException e) {
(());
} finally {
try {
if (client != null) {
();
}
} catch (IOException e) {}
}
}
}