Java實現Socket5代理服務器

openkk 12年前發布 | 52K 次閱讀 Java Java開發

直接貼代碼,不解釋

1 主服務,用來偵聽端口

package org.javaren.proxy;

import java.net.ServerSocket;
import java.net.Socket;

public class SocketProxy {
    /**
     * @param args
     */
    public static void main(String[] args) throws Exception {
        ServerSocket serverSocket = new ServerSocket(8888);
        while (true) {
            Socket socket = null;
            try {
                socket = serverSocket.accept();
                new SocketThread(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;

public class SocketThread extends Thread {
    private Socket socketIn;
    private InputStream isIn;
    private OutputStream osIn;
    //
    private Socket socketOut;
    private InputStream isOut;
    private OutputStream osOut;

    public SocketThread(Socket socket) {
        this.socketIn = socket;
    }

    private byte[] buffer = new byte[4096];
    private static final byte[] VER = { 0x5, 0x0 };
    private static final byte[] CONNECT_OK = { 0x5, 0x0, 0x0, 0x1, 0, 0, 0, 0, 0, 0 };

    public void 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 = new Socket(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));
            SocketThreadOutput out = new SocketThreadOutput(isIn, osOut);
            out.start();
            SocketThreadInput in = new SocketThreadInput(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");
    }

    public static String findHost(byte[] bArray, int begin, int end) {
        StringBuffer sb = new StringBuffer();
        for (int i = begin; i <= end; i++) {
            sb.append(Integer.toString(0xFF & bArray[i]));
            sb.append(".");
        }
        sb.deleteCharAt(sb.length() - 1);
        return sb.toString();
    }

    public static int findPort(byte[] bArray, int begin, int end) {
        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
    public static final String bytesToHexString(byte[] bArray, int begin, int end) {
        StringBuffer sb = new StringBuffer(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;

public class SocketThreadInput extends Thread {
    private InputStream isOut;
    private OutputStream osIn;

    public SocketThreadInput(InputStream isOut, OutputStream osIn) {
        this.isOut = isOut;
        this.osIn = osIn;
    }

    private byte[] buffer = new byte[409600];

    public void run() {
        try {
            int len;
            while ((len = isOut.read(buffer)) != -1) {
                if (len > 0) {
                    System.out.println(new String(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
 * 
 */
public class SocketThreadOutput extends Thread {
    private InputStream isIn;
    private OutputStream osOut;

    public SocketThreadOutput(InputStream isIn, OutputStream osOut) {
        this.isIn = isIn;
        this.osOut = osOut;
    }

    private byte[] buffer = new byte[409600];

    public void run() {
        try {
            int len;
            while ((len = isIn.read(buffer)) != -1) {
                if (len > 0) {
                    System.out.println(new String(buffer, 0, len));
                    osOut.write(buffer, 0, len);
                    osOut.flush();
                }
            }
        } catch (Exception e) {
            System.out.println("SocketThreadOutput leave");
        }
    }
}

 

效果還不錯,用firefox/ ie都測試過,可用。

轉自:http://blog.csdn.net/java2000_net/article/details/7826660

 本文由用戶 openkk 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!