`

JAVA实现socket5代理

    博客分类:
  • JAVA
阅读更多
package test;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Arrays;


public class SocketProxy {
	
	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception {
		ServerSocket serverSocket = new ServerSocket(8080);
		while (true) {
			Socket socket = null;
			try {
				socket = serverSocket.accept();
				new SocketThread(socket).start();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

}

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 };
	private static final byte[] VER = { 5, 0};
	private static final byte[] CONNECT_OK = { 5, 0, 0, 1, 0, 0, 0, 0, 0, 0 };
	
	static{
		System.out.println(Arrays.toString(VER));
		System.out.println(Arrays.toString(CONNECT_OK));
	}

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


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


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

 /*

代码是摘取别人的,我测试了一下火狐可以用
但是 findHost 方法获取端口有问题,80端口没有问题
如果是:9999,8978 ....等等会有问题
socket发送过来的是 长度为10的byte数组
IP: byte[4-8]字节转字符串用 . 分割就可以了  xx.xx.xx.xx 
端口不知道是怎么转换的例如9999,字节数组byte[9-10] 就是 39,15
端口问题尝试看看一下连接
http://ethen.iteye.com/blog/783338
原文连接:
http://www.open-open.com/lib/view/open1344004339456.html
*/

 

分享到:
评论
1 楼 lcc159591 2017-09-26  
java.net.SocketException: Malformed reply from SOCKS server
at java.net.SocksSocketImpl.readSocksReply(SocksSocketImpl.java:129)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:503)
at java.net.Socket.connect(Socket.java:579)
at java.net.Socket.connect(Socket.java:528)

本地发起请求 报错 怎么解决

相关推荐

Global site tag (gtag.js) - Google Analytics