使用Java开发代理
IPv6Only
package com.github.monkeywie.proxyee; import java.io.*; import java.net.*; import java.util.concurrent.*; public class IPv6OnlyProxy { private static final int PROXY_PORT = 9999; private static final ExecutorService threadPool = Executors.newCachedThreadPool(); public static void main(String[] args) { // 强制JVM使用IPv6 System.setProperty("java.net.preferIPv6Addresses", "true"); System.setProperty("java.net.preferIPv4Stack", "false"); try { // 创建IPv6服务器套接字 ServerSocket serverSocket = new ServerSocket(); serverSocket.bind(new InetSocketAddress("::", PROXY_PORT)); System.out.println("IPv6 Only Proxy Server running on port " + PROXY_PORT); while (true) { Socket clientSocket = serverSocket.accept(); threadPool.submit(() -> handleClient(clientSocket)); } } catch (IOException e) { e.printStackTrace(); } } private static void handleClient(Socket clientSocket) { try { // 读取客户端请求 BufferedReader clientReader = new BufferedReader( new InputStreamReader(clientSocket.getInputStream())); // 解析请求行 String requestLine = clientReader.readLine(); if (requestLine == null) return; String[] parts = requestLine.split(" "); if (parts.length < 2) return; String method = parts[0]; String urlStr = parts[1]; // 解析目标主机和端口 URL url; try { url = new URL(urlStr); } catch (MalformedURLException e) { // 处理CONNECT方法(HTTPS) if (method.equalsIgnoreCase("CONNECT")) { String[] hostPort = urlStr.split(":"); String host = hostPort[0]; int port = hostPort.length > 1 ? Integer.parseInt(hostPort[1]) : 443; handleHttpsConnect(clientSocket, host, port); return; } throw e; } String host = url.getHost(); int port = url.getPort() != -1 ? url.getPort() : url.getDefaultPort(); // 只允许IPv6连接 InetAddress[] addresses = Inet6Address.getAllByName(host); if (addresses.length == 0) { sendErrorResponse(clientSocket, "No IPv6 address available for " + host); return; } InetAddress ipv6Only=null; for(int i=0;i<addresses.length;i++){ InetAddress ia=addresses[i]; if(ia instanceof Inet6Address){ ipv6Only=ia; } System.out.println("host:"+host+ " addr:"+new String(ia.getAddress())); } if(ipv6Only==null){ return; } // 连接到目标服务器(IPv6) try (Socket serverSocket = new Socket()) { //serverSocket.connect(new InetSocketAddress(addresses[0], port), 5000); serverSocket.connect(new InetSocketAddress(ipv6Only, port), 5000); // 转发请求 if (method.equalsIgnoreCase("CONNECT")) { // HTTPS连接已在上方处理 return; } // HTTP请求 OutputStream serverOut = serverSocket.getOutputStream(); PrintWriter serverWriter = new PrintWriter(serverOut, true); // 发送请求行 serverWriter.println(requestLine); // 转发头部 String line; while (!(line = clientReader.readLine()).isEmpty()) { serverWriter.println(line); } serverWriter.println(); // 转发响应 InputStream serverIn = serverSocket.getInputStream(); OutputStream clientOut = clientSocket.getOutputStream(); byte[] buffer = new byte[4096]; int bytesRead; while ((bytesRead = serverIn.read(buffer)) != -1) { clientOut.write(buffer, 0, bytesRead); } } } catch (Exception e) { e.printStackTrace(); } finally { try { clientSocket.close(); } catch (IOException e) { e.printStackTrace(); } } } private static void handleHttpsConnect(Socket clientSocket, String host, int port) { try { // 解析IPv6地址 InetAddress[] addresses = Inet6Address.getAllByName(host); if (addresses.length == 0) { sendErrorResponse(clientSocket, "No IPv6 address available for " + host); return; } InetAddress ipv6Only=null; for(int i=0;i<addresses.length;i++){ InetAddress ia=addresses[i]; if(ia instanceof Inet6Address){ ipv6Only=ia; } System.out.println("host:"+host+ " addr:"+new String(ia.getAddress())); } if(ipv6Only==null){ return; } // 连接到目标服务器 try (Socket serverSocket = new Socket()) { //serverSocket.connect(new InetSocketAddress(addresses[0], port), 5000); serverSocket.connect(new InetSocketAddress(ipv6Only, port), 5000); // 发送200 Connection Established响应 PrintWriter clientWriter = new PrintWriter(clientSocket.getOutputStream(), true); clientWriter.println("HTTP/1.1 200 Connection Established"); clientWriter.println("Proxy-agent: IPv6-Only-Proxy/1.0"); clientWriter.println(); clientWriter.flush(); // 双向转发数据 forwardData(clientSocket, serverSocket); } } catch (Exception e) { e.printStackTrace(); } } private static void forwardData(Socket source, Socket destination) { threadPool.submit(() -> { try { InputStream in = source.getInputStream(); OutputStream out = destination.getOutputStream(); byte[] buffer = new byte[4096]; int bytesRead; while ((bytesRead = in.read(buffer)) != -1) { out.write(buffer, 0, bytesRead); } } catch (IOException e) { // 连接关闭 } }); try { InputStream in = destination.getInputStream(); OutputStream out = source.getOutputStream(); byte[] buffer = new byte[4096]; int bytesRead; while ((bytesRead = in.read(buffer)) != -1) { out.write(buffer, 0, bytesRead); } } catch (IOException e) { // 连接关闭 } } private static void sendErrorResponse(Socket clientSocket, String message) { try { PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); out.println("HTTP/1.1 502 Bad Gateway"); out.println("Content-Type: text/plain"); out.println(); out.println("502 Bad Gateway: " + message); out.flush(); } catch (IOException e) { e.printStackTrace(); } } }
相关阅读
评论:
↓ 广告开始-头部带绿为生活 ↓
↑ 广告结束-尾部支持多点击 ↑