Java 實現HTTP代理服務器


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");
        }
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM