package work;
import java.io.*;
import java.net.*;
public class MMProxy extends Thread {
static public int CONNECT_RETRIES = 5; //尝试与目标主机连接次数
static public int CONNECT_PAUSE = 5; //每次建立连接的间隔时间
static public int TIME_OUT = 50;//每次尝试连接的最大时间
static public int BUFSIZ = 4096; //缓冲区最大字节数
protected static Socket csocket;//与客户端相连的socket
public MMProxy(Socket cs) {
csocket = cs;
start();
}
public void run() {
String buffer = "";//请求头
String host = "";//目标主机IP地址
String URL = "";//请求URL
int port = 8080;
Socket ssocket = null;//套接字
InputStream cinput = null, sinput = null;//cinput为客户输入流,sinput为服务器输入流
OutputStream coutput = null, soutput = null;//coutput为客户输出流,soutput服务器输出流
try {//服务器监听客户端的套接字
csocket.setSoTimeout(TIME_OUT);//超过了50则返回一个异常
cinput = csocket.getInputStream();
coutput = csocket.getOutputStream();
while (true) {//服务端读来自客户端的输入流
int c = cinput.read();
if (c == -1) {
break;//-1为结尾标志
}
if (c == '\r' || c == '\n') {
break;
}
buffer = buffer + (char) c;//读取第一行的数据
}
URL = getRequestURL(buffer);
int n;
n = URL.indexOf("//");//找到URL中“//”的位置
if (n != -1) {
host = URL.substring(n + 2);
}
n = host.indexOf("/");
if (n != -1) {
host = host.substring(0, n);//抽取host
}
n = host.indexOf(":");//分析端口号
if (n != -1) {
port = Integer.parseInt(host.substring(n + 1));
host = host.substring(0, n);
}
int tetry = CONNECT_RETRIES;
while (tetry-- != 0) {//尝试与目标主机建立连接
try {
ssocket = new Socket(host, port);
break;
} catch (Exception e) {
}
Thread.sleep(CONNECT_PAUSE);//等待
}
if (ssocket != null) {
ssocket.setSoTimeout(TIME_OUT);
sinput = ssocket.getInputStream();
soutput = ssocket.getOutputStream();
soutput.write(buffer.getBytes());
System.out.println(buffer);
pipe(cinput, sinput, coutput, soutput);//pipe在两个socket之间进行读写
//SocketAddress address=new InetSocketAddress("192.168.0.1",8080);
//Proxy proxy=new Proxy(Proxy.Type.HTTP,address);
//URL pageUrl=new URL(host);
//HttpURLConnection httpUrlConn = (HttpURLConnection)pageUrl.openConnection(proxy);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
csocket.close();
cinput.close();
coutput.close();
} catch (Exception e1) {
System.out.println("\nClient Socket Closed Exception:");
e1.printStackTrace();
}
try {
ssocket.close();
sinput.close();
soutput.close();
} catch (Exception e2) {
System.out.println("\nServer Socket Closed Exception:");
e2.printStackTrace();
}
}
}
public String getRequestURL(String buffer) {//读取URL第一行
String[] tokens = buffer.split(" ");
String URL = "";
for (int i = 0; i < tokens.length; i++) {
if (tokens[i].startsWith("http://")) {
URL = tokens[i];
break;
}
}
return URL;
}
public void pipe(InputStream cinput, InputStream sinput, OutputStream coutput, OutputStream soutput) {//主机与代理服务器的数据通道
try {
int length;
byte bytes[] = new byte[BUFSIZ];
while (true) {
try {
while ((length = cinput.read(bytes)) > 0) {
soutput.write(bytes, 0, length);
}
//else if(length<0)break;
} catch (SocketTimeoutException e) {
} catch (InterruptedIOException e) {
System.out.println("\nRequest Exception:");
e.printStackTrace();
}
try {
while ((length = sinput.read(bytes)) > 0) {
coutput.write(bytes, 0, length);
}
//else if (length<0) ;
// break;
} catch (SocketTimeoutException e) {
} catch (InterruptedIOException e) {
System.out.println("\nResponse Exception:");
e.printStackTrace();
}
}
} catch (Exception e0) {
System.out.println("Pipe异常: " + e0);
}
}
public static void main(String args[]) {
try {
ServerSocket ssock = new ServerSocket(8080);//监听端口8080
while (true) {
Socket lsocket = ssock.accept();//使sever端处于等待状态,直到接受来自客户端的请求,并返回一个与客户通信的socket对象
new MMProxy(lsocket);//.start();//从请求中取出连接,这时已经建立好了与客户端的双向连接
}
} catch (IOException e) {
e.printStackTrace();
}
}
}