Java Socket穿越SOCKS4代理服务器

工作需要,需要用Java Socket穿越SOCKS代理服务器,网上胡乱搜一通,别怪哥说话难听,什么TMD的System.getProperties().put(......),java.net.Proxy全都不行,气急败坏,哥直接看协议去。

中文版SOCK4协议地址:http://zh.wikipedia.org/wiki/SOCKS

英文版SOCK5协议地址:http://www.ietf.org/rfc/rfc1928.txt

要想穿越代理服务器,必须要与代理服务器进行TCP连接,并实现一次或者多次握手过程。

拿SOCK4协议举例(本人代理环境为SOCK4,经测试已成功穿越)。

仔细阅读SOCK4协议,客户端要想穿越SOCK4协议与外网相连,需有一次握手过程,即客户端需向代理服务器发送一个字节序列,根据协议规范,我发送的字节序列为:

{0x04,0x01,0x1f,(byte)0x41,(byte)0xd3,(byte)0x8a,(byte)0xe0,0x35,0x00}

其中:

0X04:协议版本

0X01:CONNECT请求(0X02时为BIND请求)

0X1F 0X41:访问的外网端口(8001)

0XD3 0X8A 0XE0 0X35:访问的外网IP地址(211.138.224.53)

0X00:(相当于结束位的标志)

连接成功后,服务器端会返回应答序列,序列含义见SOCKS4协议(详细不再讲解)

握手成功后,Socket就可以按照和一般方式进行与外网服务器的通信了。

最后给出实现代码:

		//穿越Socke4代理服务
		Socket socket = new Socket("isasrv.hn.cmcc",1080);//代理服务器地址和端口
		byte[] datas = {0x04,0x01,0x1f,(byte)0x41,(byte)0xd3,(byte)0x8a,(byte)0xe0,0x35,0x00};//发送的握手字节序列
		OutputStream os = socket.getOutputStream();
		os.write(datas);
		byte[] receive = new byte[8]; //服务端返回的字节
		InputStream is = socket.getInputStream();
		int count = 0;
		if((count = is.read(receive)) > 0) { //一定要先读服务器返回的字节序列
			//System.out.println(count);
			for(byte b : receive) {
				System.out.println(Integer.toHexString((int)b));
			}
		}
		os.write(...);//按照常规方式读写数据吧
		receive = new byte[140];
		is.close();
		os.close();
		socket.close();

 

在资料搜寻过程中发现了一个可以利用的现成类库jsocks,项目地址:http://jsocks.sourceforge.net/

有兴趣的可以去看下,实现机制完全相同。

有什么问题,留言吧!切记,出现问题不要幻想网上会给你指路,最终还是要靠自己!

你可能感兴趣的:(JavaSE)