Java 實現HTTP代理服務器
1. 主服務,用來偵聽端口:
package org.javaren.proxy;
import java.net.ServerSocket;
import java.net.Socket;
publicclassSocketProxy{
/**
* @param args
*/
publicstaticvoid main(String[] args)throwsException{
ServerSocket serverSocket =newServerSocket(8888);
while(true){
Socket socket =null;
try{
socket = serverSocket.accept();
newSocketThread(socket).start();
}catch(Exception e){
e.printStackTrace();
}
}
}
}
2. 核心代碼,處理鏈接的代理線程,內部設計了Socket的認證:
package org.javaren.proxy;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
publicclassSocketThreadextendsThread{
privateSocket socketIn;
privateInputStream isIn;
privateOutputStream osIn;
//
privateSocket socketOut;
privateInputStream isOut;
privateOutputStream osOut;
publicSocketThread(Socket socket){
this.socketIn = socket;
}
privatebyte[] buffer =newbyte[4096];
privatestaticfinalbyte[] VER ={0x5,0x0};
privatestaticfinalbyte[] CONNECT_OK ={0x5,0x0,0x0,0x1,0,0,0,0,0,0};
publicvoid run(){
try{
System.out.println("\n\na client connect "+ socketIn.getInetAddress()+":"+ socketIn.getPort());
isIn = socketIn.getInputStream();
osIn = socketIn.getOutputStream();
int len = isIn.read(buffer);
System.out.println("< "+ bytesToHexString(buffer,0, len));
osIn.write(VER);
osIn.flush();
System.out.println("> "+ bytesToHexString(VER,0, VER.length));
len = isIn.read(buffer);
System.out.println("< "+ bytesToHexString(buffer,0, len));
// 查找主機和端口
String host = findHost(buffer,4,7);
int port = findPort(buffer,8,9);
System.out.println("host="+ host +",port="+ port);
socketOut =newSocket(host, port);
isOut = socketOut.getInputStream();
osOut = socketOut.getOutputStream();
//
for(int i =4; i <=9; i++){
CONNECT_OK[i]= buffer[i];
}
osIn.write(CONNECT_OK);
osIn.flush();
System.out.println("> "+ bytesToHexString(CONNECT_OK,0, CONNECT_OK.length));
SocketThreadOutputout=newSocketThreadOutput(isIn, osOut);
out.start();
SocketThreadInputin=newSocketThreadInput(isOut, osIn);
in.start();
out.join();
in.join();
}catch(Exception e){
System.out.println("a client leave");
}finally{
try{
if(socketIn !=null){
socketIn.close();
}
}catch(IOException e){
e.printStackTrace();
}
}
System.out.println("socket close");
}
publicstaticString findHost(byte[] bArray,intbegin,intend){
StringBuffer sb =newStringBuffer();
for(int i =begin; i <=end; i++){
sb.append(Integer.toString(0xFF& bArray[i]));
sb.append(".");
}
sb.deleteCharAt(sb.length()-1);
return sb.toString();
}
publicstaticint findPort(byte[] bArray,intbegin,intend){
int port =0;
for(int i =begin; i <=end; i++){
port <<=16;
port += bArray[i];
}
return port;
}
// 4A 7D EB 69
// 74 125 235 105
publicstaticfinalString bytesToHexString(byte[] bArray,intbegin,intend){
StringBuffer sb =newStringBuffer(bArray.length);
String sTemp;
for(int i =begin; i <end; i++){
sTemp =Integer.toHexString(0xFF& bArray[i]);
if(sTemp.length()<2)
sb.append(0);
sb.append(sTemp.toUpperCase());
sb.append(" ");
}
return sb.toString();
}
}
3. 讀取線程,負責外面讀數據,寫入到請求端:
package org.javaren.proxy;
/**
* * 從外部讀取,向內部發送信息
*/
import java.io.InputStream;
import java.io.OutputStream;
publicclassSocketThreadInputextendsThread{
privateInputStream isOut;
privateOutputStream osIn;
publicSocketThreadInput(InputStream isOut,OutputStream osIn){
this.isOut = isOut;
this.osIn = osIn;
}
privatebyte[] buffer =newbyte[409600];
publicvoid run(){
try{
int len;
while((len = isOut.read(buffer))!=-1){
if(len >0){
System.out.println(newString(buffer,0, len));
osIn.write(buffer,0, len);
osIn.flush();
}
}
}catch(Exception e){
System.out.println("SocketThreadInput leave");
}
}
}
4. 寫入線程,負責讀取請求端數據,寫入到目標端:
package org.javaren.proxy;
import java.io.InputStream;
import java.io.OutputStream;
/**
* 從內部讀取,向外部發送信息
*
* @author zxq
*
*/
publicclassSocketThreadOutputextendsThread{
privateInputStream isIn;
privateOutputStream osOut;
publicSocketThreadOutput(InputStream isIn,OutputStream osOut){
this.isIn = isIn;
this.osOut = osOut;
}
privatebyte[] buffer =newbyte[409600];
publicvoid run(){
try{
int len;
while((len = isIn.read(buffer))!=-1){
if(len >0){
System.out.println(newString(buffer,0, len));
osOut.write(buffer,0, len);
osOut.flush();
}
}
}catch(Exception e){
System.out.println("SocketThreadOutput leave");
}
}
}