<< 8 | (secondByte & 0xff);if (this.destinationPort <= 0) {System.err.println(ILLEGAL_PORT_NUMBER_ERROR);return false;}return true;}// CD - SOCKS command code and should be 1 for CONNECT requestprivate boolean processSOCKScommandCode(byte code) {if (code != CONNECT_REQUEST) {System.err.println(UNKNOWN_SOCKS_COMMAND_ERROR);return false;}return true;}// DSTIPprivate boolean processDestinationIP(byte[] requestArray) {try {// SOCKS 4Aif (requestArray[4] == 0 && requestArray[5] == 0 && requestArray[6] == 0 && requestArray[7] != 0) {int start = 0;int end = 0;int i = 8;while (requestArray[i] != 0) {i++;}start = i + 1;i++;while (requestArray[i] != 0) {i++;}end = i;destinationIP = InetAddress.getByName(new String(Arrays.copyOfRange(requestArray, start, end)));}// regular SOCKSelse {destinationIP = InetAddress.getByAddress(Arrays.copyOfRange(requestArray, 4, 8));}} catch (UnknownHostException e) {System.err.println(ILLEGAL_IP_LENGTH);return false;}return true;}// request length must be minimum of length 8private boolean isRequestLengthLegal(byte[] request, byte[] response) {if (request.length < MINIMUM_REQUEST_LENGTH) {System.err.println(ILLEGAL_REQUEST_LENGTH_ERROR);return false;}// dest portresponse[2] = request[2];response[3] = request[3];// ipresponse[4] = request[4];response[5] = request[5];response[6] = request[6];response[7] = request[7];return true;}}}客户端使用Socket4代理客户端协议实现类
import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.Socket;import java.net.UnknownHostException;public class Sock4Socket extends Socket {// 版本private static byte VERSION4 = 0X04;// 请求private static byte CONNECT_REQUEST = 0X01;private static byte BIND_REQUEST = 0X02;// 结束private static byte END = 0X00;private String targetHost;private int targetPort;public Sock4Socket(String proxyHost, int proxyPort, String targetHost, int targetPort) throws UnknownHostException, IOException {super(proxyHost, proxyPort);this.targetHost = targetHost;this.targetPort = targetPort;this.connect();}/*** @param host* @param port* @return* @throws UnknownHostException*/private byte[] connByte(String host, int port) throws UnknownHostException {String[] subIP = host.split("\.");String portStr = Integer.toHexString(port);byte subP1B = 0;byte subP2B = 0;if (portStr.length() <= 2) {subP2B = (byte) Byte.valueOf(portStr, 16);} else if (portStr.length() == 3) {String p1 = portStr.charAt(0) + "";subP1B = (byte) Byte.valueOf(p1, 16);String p2 = portStr.charAt(1) + "" + portStr.charAt(2);subP2B = (byte) Byte.valueOf(p2, 16);} else if (portStr.length() == 4) {String p1 = portStr.charAt(0) + "" + portStr.charAt(1);subP1B = (byte) Byte.valueOf(p1, 16);String p2 = portStr.charAt(2) + "" + portStr.charAt(3);subP2B = (byte) Byte.valueOf(p2, 16);}byte[] bt = new byte[9];bt[0] = VERSION4;bt[1] = CONNECT_REQUEST;bt[2] = subP1B;bt[3] = subP2B;bt[4] = (byte) Integer.parseInt(subIP[0]);bt[5] = (byte) Integer.parseInt(subIP[1]);bt[6] = (byte) Integer.parseInt(subIP[2]);bt[7] = (byte) Integer.parseInt(subIP[3]);bt[8] = END;return bt;}/*** 连接*/private void connect() throws IOException {byte[] data = https://www.isolves.com/it/wlyx/fwq/2022-09-02/connByte(this.targetHost, this.targetPort);OutputStream os = this.getOutputStream();// 握手字节序列os.write(data);os.flush();// 服务端返回的字节 version,command,ip,port,messagebyte[] receive = new byte[8];InputStream is = this.getInputStream();is.read(receive);byte b = receive[1];if (b == 0) {throw new IOException("");} else if (b == 92) {throw new IOException("server time out");} else if (b == 90) {// success}}}
测试案例
import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;public class Sock4SocketClientDemo {/*** @param args* @throws Exception*/public static void main(String[] args) throws Exception {// Socket4代理服务地址String proxyHost = "127.0.0.1";int proxyPort = 1080;// 访问的地址String targetHost = "124.239.226.238";int targetPort = 80;// 创建Socket4代理SocketSock4Socket sock4Socket = new Sock4Socket(proxyHost, proxyPort, targetHost, targetPort);OutputStream outputStream = sock4Socket.getOutputStream();InputStream inputStream = sock4Socket.getInputStream();InputStreamReader isr = new InputStreamReader(inputStream, "GBK");BufferedReader br = new BufferedReader(isr);// 请求内容StringBuilder request = new StringBuilder();request.append("GET / HTTP/1.1rn");request.append("Accept-Language: zh-cnrn");request.append("Host: www.toutiao.comrn");request.append("rn");outputStream.write(request.toString().getBytes());outputStream.flush();// 响应内容StringBuilder sb = new StringBuilder();String str = null;while ((str = br.readLine()) != null) {sb.append(str + "n");}System.out.println(sb.toString());br.close();isr.close();outputStream.close();}}
推荐阅读
- JavaScript 框架大战已结束,赢家只有一个
- Java 同步工具与组合类的线程安全性分析
- 使用redisson实现分布式秒杀功能
- 使用 JavaScript 实现无限滚动
- 实现共同富裕,在农村就必须坚持?共同富裕的社会理想能否实现
- |想要实现时间自由吗?那就先让自己成为一架“全天候战斗机”吧
- |专家建议:大城市30岁还未实现经济独立的女性,趁早回老家!
- Java|Java:2022年招聘Java开发人员指南
- Java|HR傲慢对待求职者,还“诅咒”对方找不到工作,大学生也太难了
- 在Java 8及更高版本中使用Java流