📄 smtpconnection.java
字号:
package com.cwq.batchmail.mail;
import java.io.*;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.Date;
import java.util.StringTokenizer;
import com.cwq.batchmail.util.Base64;
/**
500 格式错误,命令不可识别(此错误也包括命令行过长)
501 参数格式错误
502 命令不可实现
503 错误的命令序列
504 命令参数不可实现
211 系统状态或系统帮助响应
214 帮助信息
220 服务就绪
221 服务关闭传输信道
421 服务未就绪,关闭传输信道(当必须关闭时,此应答可以作为对任何命令的响应),在sina中是too many connections,然后拒绝了
250 要求的邮件操作完成
251 用户非本地,将转发向
450 要求的邮件操作未完成,邮箱不可用(例如,邮箱忙)
550 要求的邮件操作未完成,邮箱不可用(例如,邮箱未找到,或不可访问)
451 放弃要求的操作;处理过程中出错; 或暂时的失败,就是被defer了,信在postfix的等待队列中,等一段时间就可以收到
452 要求动作无法执行:系统空间不足
454 Client was not authenticated 安全因素,被封锁
551 用户非本地,请尝试
452 系统存储不足,要求的操作未执行
522 User has too many RCPT User, 收件人过多,我设成10的时候,在163和sina中没问题,但在tom中就出现了 522
535 authorization failed
552 过量的存储分配,要求的操作未执行
553 邮箱名不可用,要求的操作未执行(例如邮箱格式错误), 或帐号已给锁定
354 开始邮件输入,以.结束
554 操作失败
445 Server Rejected 被封锁
440 邮件址错误
现在支持163,sina,sohu,3126(最后会出现451错误),yahoo开通smtp要交钱(没得测试)
**/
public class SmtpConnection {
public static final int STATE_CONNECTION_UNKNOW = 1;
public static final int STATE_CONNECTION_FAIL = 2;
public static final int STATE_CONNECTION_TIMEOUT = 3;
public static final int STATE_AUTH_UNKNOW = 4;
public static final int STATE_AUTH_FAIL = 5;
public static final int STATE_AUTH_SUCC = 6;
public static final int STATE_SEND_UNKNOW = 7;
public static final int STATE_SEND_OK = 8;
public static final int STATE_SEND_CHECKOK = 9;
public static final int STATE_SEND_FAIL = 10;
private String server = null;
private int port = 25;
private BufferedReader in = null;
private BufferedWriter out = null;
private Socket socket = null;
private String msg = "";
private boolean log = true;
public String debugname = "s1";
/**
*
*/
public static void main(String[] args) {
try {
// 20 个
String to10 = "chenweiqiangoo@163.com,164576700@qq.com";
String to20 = to10 + "," + to10;
String to30 = to10 + "," + to20;
String to100 = to30 + "," + to30 + "," + to30 + "," + to10;
SmtpConnection smtp = new SmtpConnection("127.0.0.1", 25);
smtp.open("fjftjftj@mytestqq.com", "", false);
smtp.sendMessage(new Message(
"fjftjftj@mytestqq.com",
to10,
"text/html; charset=iso-8859-1",
"f aaa Test",
"three line",
null
));
smtp.finalize();
} catch(Exception e) {
e.printStackTrace();
}
}
public SmtpConnection(String server, int port) {
this.server = server;
this.port = port;
}
public int open(String user, String pass, boolean auth) {
return open(user, pass, null, auth);
}
public int open(String user, String pass, String socksProxy, int socksProxyPort, boolean auth) {
return open(user, pass, new Proxy(Proxy.Type.SOCKS, new InetSocketAddress(socksProxy, socksProxyPort)), auth);
}
public int open(String user, String pass, Proxy proxy , boolean auth) {
String response = null;
try {
if(proxy != null)
socket = new Socket(proxy);
else
socket = new Socket(this.server, this.port);
socket.setSoTimeout(5000);
socket.setKeepAlive(true);
if(proxy != null)
socket.connect(new InetSocketAddress(this.server, this.port), 15000);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
response = read();
if(!response.startsWith("220")) {
///throw new IOException(response);
return state(STATE_CONNECTION_FAIL, response);
}
}
catch(SocketTimeoutException ex) {
return state(STATE_CONNECTION_TIMEOUT, ex.getMessage());
}
catch(IOException ex) {
//throw new SocketTimeoutException(response);
return state(STATE_CONNECTION_UNKNOW, ex.getMessage());
}
return auth(user, pass, auth);
}
protected int auth(String user, String pass, boolean auth) {
String response = "";
try {
writeln("EHLO HELO");
response = read(true);
if(!response.startsWith("250")) {
//System.out.println("aaaaaaaaaaaaaa");
return state(STATE_AUTH_UNKNOW, response);
//throw new IOException(response);
}
if(auth) {
writeln("AUTH LOGIN");
response = read();
if(!response.startsWith("334")) {
return state(STATE_AUTH_UNKNOW, response);
//throw new IOException(response);
}
writeln(Base64.encode(user)); // user
response = read();
if(!response.startsWith("334")) {
//throw new IOException(response);
return state(STATE_AUTH_UNKNOW, response);
}
writeln(Base64.encode(pass)); // pass
response = read();
if(!response.startsWith("235")) {
//throw new IOException(response);
return state(STATE_AUTH_FAIL, response);
}
}
} catch(SocketTimeoutException ex) {
return state(STATE_CONNECTION_TIMEOUT, ex.getMessage());
} catch(IOException ex) {
ex.printStackTrace();
return state(STATE_AUTH_UNKNOW, ex.getMessage());
}
return state(STATE_AUTH_SUCC, "");
}
public void close() {
try {
writeln("QUIT");
socket.close();
} catch(SocketTimeoutException e) {
} catch(IOException e) {
}
}
protected int checkResponse() {
try {
String response = read();
if(response.startsWith("4") || response.startsWith("5")) {
if(response.startsWith("5")) {
if(!response.startsWith("550"))
return state(STATE_SEND_FAIL, response);
// 550状态是找不到邮件,比如在163中,RCPT到另一·163的时候,如果另一个@163不存在,会出现550
}
else {
if(response.startsWith("421")) {
// too many connection form ip addr
//return state(STATE_SEND_FAIL, response);
}
return state(STATE_SEND_FAIL, response);
}
}
} catch(SocketTimeoutException ex) {
return state(STATE_CONNECTION_TIMEOUT, ex.getMessage());
} catch(IOException ex) {
return state(STATE_SEND_UNKNOW, ex.getMessage());
}
return STATE_SEND_CHECKOK;
}
public int sendMessage(Message msg) {
if (msg.getMessageID()==null || msg.getMessageID().equals("")) {
msg.setMessageID(SmtpConnection.createMessageID(this.server));
}
try {
socket.setSoTimeout(10000);
writeln("MAIL FROM:<" + msg.getFrom() + ">");
int state = checkResponse();
if(STATE_SEND_CHECKOK != state) return state;
StringTokenizer t = new StringTokenizer(msg.getTo(), ";,");
while(t.hasMoreTokens()) {
writeln("RCPT TO:<" + t.nextToken() + ">");
state = checkResponse();
if(STATE_SEND_CHECKOK != state) return state;
}
t = new StringTokenizer(msg.getCC(), ";,");
while(t.hasMoreTokens()) {
writeln("RCPT TO:<" + t.nextToken() + ">");
state = checkResponse();
if(STATE_SEND_CHECKOK != state) return state;
}
t = new StringTokenizer(msg.getBCC(), ";,");
while(t.hasMoreTokens()) {
writeln("RCPT TO:<" + t.nextToken() + ">");
state = checkResponse();
if(STATE_SEND_CHECKOK != state) return state;
}
writeln("DATA");
checkResponse();
for(int i = 0; i < msg.getHeader().length; i++) {
writeln(encodeDot(msg.getHeader()[i]));
}
writeln("X-Mailer: m" + System.currentTimeMillis());
writeln("");
for(int i = 0; i < msg.getBody().length; i++) {
writeln(encodeDot(msg.getBody()[i]));
}
writeln("");
writeln(".");
state = checkResponse();
if(STATE_SEND_CHECKOK != state) return state;
} catch(SocketTimeoutException ex) {
return state(STATE_CONNECTION_TIMEOUT, ex.getMessage());
} catch(IOException ex) {
return state(STATE_SEND_UNKNOW, ex.getMessage());
}
return state(STATE_SEND_OK, "");
}
protected String encodeDot(String line) {
String result = line;
if(line.startsWith(".")) {
result = "." + result;
}
return result;
}
public void finalize() {
this.close();
}
public static String createMessageID(String hostName) {
String msgID = new Date().getTime() + ".";
msgID += Thread.currentThread().hashCode();
msgID += hostName;
msgID = "<"+msgID+">";
return msgID;
}
private int state(final int state, String msg) {
System.out.println(msg);
this.msg = msg;
return state;
}
public String getErrorMessage() {
return this.msg;
}
private String read() throws SocketTimeoutException, IOException {
return read(false);
}
private String read(boolean details) throws SocketTimeoutException, IOException {
String line = null;
if(details) {
String lastLine = null;
try {
while((line = in.readLine()) != null) {
lastLine = line;
}
} catch(SocketTimeoutException ex) {
//if(log)
//System.out.println("SocketTimeoutException: " + ex.toString());
}
if(log) System.out.println(debugname + this.hashCode() + "recv: " + lastLine);
if(lastLine == null && log)
System.out.println(debugname + " Socket Timeout");
return lastLine;
}
else {
line = in.readLine();
if(log)
System.out.println(debugname + this.hashCode() + "recv: " + line);
}
return line;
}
private void writeln(String line) throws SocketTimeoutException, IOException {
out.write(line);
out.newLine();
if(log)
System.out.println(debugname + this.hashCode() + "send: " + line);
out.flush();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -