Java实现Socket5代理服务器

openkk 12年前

直接贴代码,不解释

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