Socket,http代理

參考

Java Socket編程----通信是這樣煉成的

http://developer.51cto.com/art/201509/490775.htm

JAVA Socket 實現HTTP與HTTPS客戶端發送POST與GET方式請求

http://blog.csdn.net/jia20003/article/details/17104791


Java實現Http的Post、Get、代理訪問請求

https://www.oschina.net/code/snippet_2266157_45252

java使用socket實現http簡單get請求

http://name327.iteye.com/blog/1742496



    代理服務端

1、程序入口

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class proxyd {
public static void main(final String[] args) {
if (args.length > 0 && args[0].equals("-port")) {
final int port = Integer.parseInt(args[1]);
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(port);
System.out.println("The proxy have start on port:" + port
+ "\n");
while (true) {
Socket socket = null;
try {
socket = serverSocket.accept();
new HttpProxyMainThread(socket).start();// 有一個請求就啓動一個線程
} catch (final Exception e) {
System.out.println("Thread start fail");
}
}
} catch (final IOException e1) {
System.out.println("proxyd start fail\n");
} finally {
try {
serverSocket.close();
} catch (final IOException e) {
// e.printStackTrace();
}
}
} else {
System.out.println("parameter error");
}
}
}


2、主線程

import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;


public class HttpProxyMainThread extends Thread {
static public int CONNECT_RETRIES = 5; // 嘗試與目標主機連接次數
static public int CONNECT_PAUSE = 5; // 每次建立連接的間隔時間
static public int TIMEOUT = 50; // 每次嘗試連接的最大時間
public static final String SEQUENCE = "\r\n";
protected Socket csocket;// 與客戶端連接的Socket
public HttpProxyMainThread(final Socket cs) {
this.csocket = cs;
}
@Override
public void run() {
String firstLine = ""; // http請求頭第一行
String urlStr = ""; // 請求的url
Socket ssocket = null;// 與目標服務器連接的socket
// cis爲客戶端輸入流,sis爲目標主機輸入流
InputStream cis = null, sis = null;
// cos爲客戶端輸出流,sos爲目標主機輸出流
OutputStream cos = null, sos = null;
try {
csocket.setSoTimeout(TIMEOUT);
cis = csocket.getInputStream();
cos = csocket.getOutputStream();
while (true) {
final int c = cis.read();
if (c == -1) {
break; // -1爲結尾標誌
}
if (c == '\r' || c == '\n') {
break;// 讀入第一行數據,從中獲取目標主機url
}
firstLine = firstLine + (char) c;
}
urlStr = extractUrl(firstLine);
System.out.println(urlStr);
final URL url = new URL(urlStr);// 將url封裝成對象,完成一系列轉換工作,並在getIP中實現了dns緩存
firstLine = firstLine.replace(
url.getScheme() + "://" + url.getHost(), "");// 這一步很重要,把請求頭的絕對路徑換成相對路徑
int retry = CONNECT_RETRIES;
final StringBuffer head = new StringBuffer();
while (retry-- != 0) {
try {
ssocket = new Socket(url.getIP(), url.getPort()); // 嘗試建立與目標主機的連接
// /////////////////////////////////////////////////////
// 這些是必須的
head.append("GET / HTTP/1.1" + SEQUENCE);
head.append("Host:" + url.getIP() + SEQUENCE + SEQUENCE);
// 這些是可選的
head.append("Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
head.append("Accept-Language:zh-CN,zh;q=0.8");
head.append("User-Agent:Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.11");
// /////////////////////////////////////////////////////
System.out.println("+++++successfully connect to ("
+ url.getIP() + ":" + url.getPort() + ")(host:"
+ url.getHost() + ")+++++,get resource("
+ url.getResource() + ")");
break;
} catch (final Exception e) {
System.out.println("-----fail connect to (" + url.getIP()
+ ":" + url.getPort() + ")(host:" + url.getHost()
+ ")-----");
}
// 等待
Thread.sleep(CONNECT_PAUSE);
}
if (ssocket != null) {
ssocket.setSoTimeout(TIMEOUT);
sis = ssocket.getInputStream();
sos = ssocket.getOutputStream();
sos.write(head.toString().getBytes());
sos.flush();
// sos.write(firstLine.getBytes()); // 將請求頭寫入
pipe(cis, sis, sos, cos); // 建立通信管道
}
} catch (final Exception e) {
// e.printStackTrace();
} finally {
try {
csocket.close();
cis.close();
cos.close();
} catch (final Exception e1) {
}
try {
ssocket.close();
sis.close();
sos.close();
} catch (final Exception e2) {
}
}
}


/**
* 從http請求頭的第一行提取請求的url
*
* @param firstLine
*            http請求頭第一行
* @return url
*/
public String extractUrl(final String firstLine) {
final String[] tokens = firstLine.split(" ");
String URL = "";
for (int index = 0; index < tokens.length; index++) {
if (tokens[index].startsWith("http://")) {
URL = tokens[index];
break;
}
}
return URL;
}


/**
* 爲客戶機與目標服務器建立通信管道
*
* @param cis
*            客戶端輸入流
* @param sis
*            目標主機輸入流
* @param sos
*            目標主機輸出流
* @param cos
*            客戶端輸出流
*/
public void pipe(final InputStream cis, final InputStream sis,
final OutputStream sos, final OutputStream cos) {
final Client2ServerThread c2s = new Client2ServerThread(cis, sos);
final Server2ClientThread s2c = new Server2ClientThread(sis, cos);
c2s.start();
s2c.start();
try {
c2s.join();
s2c.join();
} catch (final InterruptedException e1) {


}
}
}


3、Client2ServerThread

import java.io.InputStream;
import java.io.OutputStream;


public class Client2ServerThread extends Thread {
private final InputStream cis;
private final OutputStream sos;


public Client2ServerThread(final InputStream cis, final OutputStream sos) {
this.cis = cis;
this.sos = sos;
}


@Override
public void run() {
int length;
final byte bytes[] = new byte[1024];
while (true) {
try {
if ((length = cis.read(bytes)) > 0) {
sos.write(bytes, 0, length);// 將http請求頭寫到目標主機
sos.flush();
} else if (length < 0) {
break;
}
} catch (final Exception e) {
// System.out.println("\nRequest Exception:");
// e.printStackTrace();
}
}
}
}

4、Server2ClientThread

import java.io.InputStream;
import java.io.OutputStream;


public class Server2ClientThread extends Thread {
private final InputStream sis;
private final OutputStream cos;


public Server2ClientThread(final InputStream sis, final OutputStream cos) {
this.sis = sis;
this.cos = cos;
}


@Override
public void run() {
int length;
final byte bytes[] = new byte[1024];
while (true) {
try {
if ((length = sis.read(bytes)) > 0) {
cos.write(bytes, 0, length);// 將http請求頭寫到目標主機
cos.flush();
} else if (length < 0) {
break;
}
} catch (final Exception e) {
// System.out.println("\nRequest Exception:");
}
}
}
}

5、工具類

import java.net.InetAddress;
import java.net.UnknownHostException;


public class URL {
private String scheme;
private String host;
private String IP;
private String resource;
private int port;


public String getScheme() {
return scheme;
}


public void setScheme(final String schemes) {
this.scheme = schemes;
}


public String getHost() {
return host;
}


public void setHost(final String host) {
this.host = host;
}


public int getPort() {
return port;
}


public void setPort(final int port) {
this.port = port;
}


public String getIP() {
java.security.Security.setProperty("networkaddress.cache.ttl", "30");
try {
this.IP = InetAddress.getByName(this.host).getHostAddress();
} catch (final UnknownHostException e) {
return "";
}
return this.IP;
}


public String getResource() {
return resource;
}


@Override
public String toString() {
return "scheme:" + this.getScheme() + "\nhost:" + this.getHost()
+ "\nport:" + this.getPort() + "\nIP:" + this.getIP()
+ "\nResource:" + this.getResource();
}


public URL(final String url) {
String scheme = "http";
String host = "";
String port = "80";
int index;
// 抽取host
index = url.indexOf("//");
if (index != -1) {
scheme = url.substring(0, index - 1);
}
host = url.substring(index + 2);
index = host.indexOf('/');
if (index != -1) {
this.resource = host.substring(index);
host = host.substring(0, index);
}
index = host.indexOf(':');
if (index != -1) {
port = host.substring(index + 1);
host = host.substring(0, index);
}
this.scheme = scheme;
this.host = host;
this.port = Integer.parseInt(port);
}
}

6、客戶端

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.Socket;
import java.net.URL;
import java.net.URLConnection;


public class Client1 {
public static void main(final String[] args) throws Exception {
proxy();
}


public static void proxy() throws IOException {
final URL url = new URL("http://www.baidu.com");// 創建一個代理服務器對象
final Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(
"localhost", 8080));// 使用指定的代理服務器打開連接
final URLConnection conn = url.openConnection(proxy);// 設置超時時長
final BufferedReader in = new BufferedReader(new InputStreamReader(
conn.getInputStream()));
String s = "";
while ((s = in.readLine()) != null) {
System.out.println(s);
}
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章