这个程序没有使用JavaMail API而是根据SMTP协议的要求直接处理协议的细节发送邮件虽然比较麻烦了一些但是对了解邮件协议的细节很有帮助的
本文分两部分第一部分是SMTP命令介绍(这个从别的地方抄的嘿嘿)第二部分通过一个实例真正理解一下发送邮件的过程
一SMTP 命令简介
什么是 SMTP
SMTP (Simple Mail Transfer Protocol) : 电子邮件从客户机传输到服务器或从某一个服务器传输到另一个服务器使用的传输协议 SMTP 是请求/响应协议命令和响应都是基于 ASCII 文本并以 CR 和 LF 符结束响应包括一个表示返回状态的三位数字代码SMTP 在 TCP 协议 端口监听连接请求
什么是 ESMTP
ESMTP (Extended SMTP)顾名思义扩展 SMTP 就是对标准 SMTP 协议进行的扩展它与 SMTP 服务的区别仅仅是使用 SMTP 发信不需要验证用户帐户而用 ESMTP 发信时服务器会要求用户提供用户名和密码以便验证身份验证之后的邮件发送过程与 SMTP 方式没有两样
SMTP 命令包括
HELO 向服务器标识用户身份发送者能欺骗说谎但一般情况下服务器都能检测到
EHLO 向服务器标识用户身份发送者能欺骗说谎但一般情况下服务器都能检测到
MAIL FROM 命令中指定的地址是发件人地址
RCPT TO 标识单个的邮件接收人可有多个 RCPT TO常在 MAIL 命令后面
DATA 在单个或多个 RCPT 命令后表示所有的邮件接收人已标识并初始化数据传输以 CRLFCRLF 结束
VRFY 用于验证指定的用户/邮箱是否存在由于安全方面的原因服务器常禁止此命令
EXPN 验证给定的邮箱列表是否存在扩充邮箱列表也常被禁用
HELP 查询服务器支持什么命令
NOOP 无操作服务器应响应 OK
RSET 重置会话当前传输被取消
QUIT 结束会话
连接到 Postfix 使用 SMTP 命令发送邮件
例如安装 Postfix 的邮件服务器IP是 (蓝色字体内容由客户端输入红色字体内容是服务返回的)
telnet 使用 telnet 命令连接服务器 端口
helo 向服务器标识用户身份发送 mail from 命令
ehlo ESMTP 命令发信需要认证
auth login 进行用户身份认证
VXNlcmhbWU
YzdGFAYWheGlLmldA== BASE 加密后的用户名
UGFzcdvcmQ
MTkMjIxNA== BASE 加密后的密码
authentication successfully 身份认证成功
( authentication failed 身份认证失败)
发到本系统中域名下的账户可跳过身份认证
mail from: <> mail from 地址
ok 命令执行成功
rcpt to: <> 递送给地址
ok 命令执行成功
data 数据传输初始化
End data with 开始传输数据
From:
To:
Date: Mon Oct :: +
Subject: test mail
Hi test
This is a test mail you dont reply it
数据内容包括BASE加密后的邮件内容 以 CRLFCRLF 结束数据传输
OK: queued as FDE 命令执行成功
quit 结束会话
Bye
Connection closed by foreign host 断开连接
以上就是一个邮件发送的基本的命令
再说一下邮件发送的基本过程
如果你的邮件地址是而你要用这个邮箱发送一封邮件到你需要连接到服务器上当然这个连接可能需要认证现在基本上都要验证然后是发送邮件到服务器上关闭连接在上你所发送的邮件进入发送队列中轮到你要发送的邮件时主机再联系将邮件传输到服务器上
二实例应用
MailMessageJava
//这个类其实就是一个基本的JavaBean用于完成一些基本信息的设置也可以不要这个东西直接在程序中写明就可以不过这样条理较清楚一些而且修改也方便一些
package mail;
public class MailMessage {
private String from;
private String to;
private String datafrom;
private String datato;
private String subject;
private String content;
private String date;
private String user;
private String password;
public String getPassword() {
return password;
}
public void setPassword(String password) {
thispassword = password;
}
public String getUser() {
return user;
}
public void setUser(String user) {
thisuser = user;
}
public String getContent() {
return content;
}
public void setContent(String content) {
ntent = content;
}
public String getDatafrom() {
return datafrom;
}
public void setDatafrom(String datafrom) {
thisdatafrom = datafrom;
}
public String getDatato() {
return datato;
}
public void setDatato(String datato) {
thisdatato = datato;
}
public String getDate() {
return date;
}
public void setDate(String date) {
thisdate = date;
}
public String getFrom() {
return from;
}
public void setFrom(String from) {
thisfrom = from;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
thissubject = subject;
}
public String getTo() {
return to;
}
public void setTo(String to) {
thisto = to;
}
}
SMTPClient Java
//主要的功能就在这里面完成了
package mail;
import JavaioBufferedReader;
import JavaioBufferedWriter;
import JavaioIOException;
import JavaioInputStreamReader;
import JavaioOutputStreamWriter;
import Socket;
import SocketException;
import UnknownHostException;
import JavautilStringTokenizer;
import sunmiscBASEEncoder;
public class SMTPClient {
private boolean debug=true;
BASEEncoder encode=new BASEEncoder();//用于加密后发送用户名和密码
public static void main(String[] args) throws UnknownHostException IOException {
// TODO Autogenerated method stub
MailMessage message=new MailMessage();
messagesetFrom(mailto:%);//发件人
messagesetTo(mailto:%);//收件人
String server=;//邮件服务器
messagesetSubject(test);//邮件主题
messagesetContent(test);//邮件内容
messagesetDatafrom(mailto:%);//发件人在邮件的发件人栏目中显示
messagesetDatato(mailto:%);//收件人在邮件的收件人栏目中显示
messagesetUser(wasingmon);//登陆邮箱的用户名
messagesetPassword();//登陆邮箱的密码
SMTPClient smtp=new SMTPClient(server);
boolean flag;
flag=smtpsendMail(messageserver);
if(flag){
Systemoutprintln(邮件发送成功!);
}
else{
Systemoutprintln(邮件发送失败!);
}
}
private Socket socket;
public SMTPClient(String serverint port) throws UnknownHostException IOException{
try{
socket=new Socket(server);
}catch(SocketException e){
Systemoutprintln(egetMessage());
}catch(Exception e){
eprintStackTrace();
}finally{
Systemoutprintln(已经建立连接!);
}
}
//注册到邮件服务器
public void helo(String serverBufferedReader inBufferedWriter out) throws IOException{
int result;
result=getResult(in);
//连接上邮件服务后服务器给出应答
if(result!=){
throw new IOException(连接服务器失败);
}
result=sendServer(HELO +serverinout);
//HELO命令成功后返回
if(result!=)
{
throw new IOException(注册邮件服务器失败!);
}
}
private int sendServer(String strBufferedReader inBufferedWriter out) throws IOException{
outwrite(str);
outnewLine();
outflush();
if(debug)
{
Systemoutprintln(已发送命令:+str);
}
return getResult(in);
}
public int getResult(BufferedReader in){
String line=;
try{
line=inreadLine();
if(debug){
Systemoutprintln(服务器返回状态:+line);
}
}catch(Exception e){
eprintStackTrace();
}
//从服务器返回消息中读出状态码将其转换成整数返回
StringTokenizer st=new StringTokenizer(line );
return IntegerparseInt(stnextToken());
}
public void authLogin(MailMessage messageBufferedReader inBufferedWriter out) throws IOException{
int result;
result=sendServer(AUTH LOGINinout);
if(result!=){
throw new IOException(用户验证失败!);
}
result=sendServer(encodeencode(messagegetUser()getBytes())inout);
if(result!=){
throw new IOException(用户名错误!);
}
result=sendServer(encodeencode(messagegetPassword()getBytes())inout);
if(result!=){
throw new IOException(验证失败!);
}
}
//开始发送消息邮件源地址
public void mailfrom(String sourceBufferedReader inBufferedWriter out) throws IOException{
int result;
result=sendServer(MAIL FROM:<+source+>inout);
if(result!=){
throw new IOException(指定源地址错误);
}
}
// 设置邮件收件人
public void rcpt(String touchmanBufferedReader inBufferedWriter out) throws IOException{
int result;
result=sendServer(RCPT TO:<+touchman+>inout);
if(result!=){
throw new IOException(指定目的地址错误!);
}
}
//邮件体
public void data(String fromString toString subjectString contentBufferedReader inBufferedWriter out) throws IOException{
int result;
result=sendServer(DATAinout);
//输入DATA回车后若收到应答后继续输入邮件内容
if(result!=){
throw new IOException(不能发送数据);
}
outwrite(From: +from);
outnewLine();
outwrite(To: +to);
outnewLine();
outwrite(Subject: +subject);
outnewLine();
outnewLine();
outwrite(content);
outnewLine();
//句号加回车结束邮件内容输入
result=sendServer(inout);
Systemoutprintln(result);
if(result!=)
{
throw new IOException(发送数据错误);
}
}
//退出
public void quit(BufferedReader inBufferedWriter out) throws IOException{
int result;
result=sendServer(QUITinout);
if(result!=){
throw new IOException(未能正确退出);
}
}
//发送邮件主程序
public boolean sendMail(MailMessage messageString server){
try{
BufferedReader in=new BufferedReader(new InputStreamReader(socketgetInputStream()));
BufferedWriter out=new BufferedWriter(new OutputStreamWriter(socketgetOutputStream()));
helo(serverinout);//HELO命令
authLogin(messageinout);//AUTH LOGIN命令
mailfrom(messagegetFrom()inout);//MAIL FROM
rcpt(messagegetTo()inout);//RCPT
data(messagegetDatafrom()messagegetDatato()messagegetSubject()messagegetContent()inout);//DATA
quit(inout);//QUIT
}catch(Exception e){
eprintStackTrace();
return false;
}
return true;
}
}
因为现在一般SMTP服务器都需要SMTP验证所以本例子中也加入了这个验证要不然邮件时发不出去的(刚开始我就这样)