直接贴代码,不解释
1 主服务,用来侦听端口
[java] view plaincopy
- 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的认证,自己看吧
[java] view plaincopy
- 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 读取线程,负责外面读数据,写入到请求端
[java] view plaincopy
- 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 写入线程,负责读取请求端数据,写入到目标端
[java] view plaincopy
- 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");
- }
- }
- }
原文:http://blog.csdn.net/java2000_net/article/details/7826660
时间: 2024-11-02 20:58:16