Java实现http代理服务器 Java实现http代理服务器
本⽂连接:
gitee:
默认端⼝:8888
javac RuphyHttpProxy.java
java RuphyHttpProxy 11111
代码如下:
//package me.muphy.servicce;
import java.io.Closeable;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.ServerSocket;
import java.Socket;
import urrent.CountDownLatch;
import urrent.TimeUnit;
import Matcher;
import Pattern;
/**
* http代理
*/
public class RuphyHttpProxy extends Thread {
private final ServerSocket server;
private final int port;
public RuphyHttpProxy(int port) throws IOException {
this.port = port;
server = new ServerSocket(port);
System.out.println("代理端⼝:" + this.port);
}
public static void main(String[] args) throws IOException {
int port = 8888;
if (args != null && args.length > 0 && args[0].matches("\\d+")) {
port = Integer.parseInt(args[0]);
}
new RuphyHttpProxy(port).start();
}
@Override
public void run() {
// 线程运⾏函数
while (true) {
try {
Socket client = server.accept();
//使⽤线程处理收到的请求
new HttpConnectThread(client).start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 新连接处理线程
*/
private static class HttpConnectThread extends Thread {
private Socket client;
private Socket server = null;
private String host = null;
private int port = 80;
private int clientReadLength = 0;
byte clientInputBuffer[] = new byte[1024 * 1024 * 4];
private DataInputStream clientInputStream = null; //客户端输⼊流
private DataInputStream serverInputStream = null; //服务端输⼊流
private DataOutputStream clientOutputStream = null; //客户端输出流
private DataOutputStream serverOutputStream = null;  //服务端输出流
private long createTime = System.currentTimeMillis();
private String clientInputString = null;
public HttpConnectThread(Socket client) {
this.client = client;
}
@Override
public void run() {
try {
clientInputStream = new InputStream());
clientOutputStream = new OutputStream());
if (clientInputStream != null && clientOutputStream != null) {
clientReadLength = ad(clientInputBuffer, 0, clientInputBuffer.length); // 从客户端读数据if (clientReadLength > 0) { // 读到数据
clientInputString = new String(clientInputBuffer, 0, clientReadLength);
if (ains("\n")) {
clientInputString = clientInputString.substring(0, clientInputString.indexOf("\n"));
}
if (ains("CONNECT ")) {
parseServerHost("CONNECT ([^ ]+) HTTP/");
} else if (ains("") && ains("HTTP/")) {
// 从所读数据中取域名和端⼝号
parseServerHost("([^/]+)/");
}
if (host != null) {
server = new Socket(host, port);
java stream/
/ 根据读到的域名和端⼝号建⽴套接字
serverInputStream = new InputStream());
serverOutputStream = new OutputStream());
if (serverInputStream != null && serverOutputStream != null && server != null) {
if (ains("CONNECT ")) {
doConnect();
return;
}
doRequest();
return;
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
IOUtils.close(serverInputStream, serverOutputStream, server, clientInputStream, clientOutputStream, client);
}
/**
* 解析主机地址
*
* @param regExp
*/
private void parseServerHost(String regExp) {
Pattern pattern = Patternpile(regExp);
Matcher matcher = pattern.matcher(clientInputString + "/");
if (matcher.find()) {
host = up(1);
if (ains(":")) {
port = Integer.parseInt(host.substring(host.indexOf(":") + 1));
host = host.substring(0, host.indexOf(":"));
}
}
}
/**
* 处理请求
*
* @throws IOException
*/
private void doRequest() throws IOException, InterruptedException {
serverOutputStream.write(clientInputBuffer, 0, clientReadLength);
serverOutputStream.flush();
final CountDownLatch latch;
if (ains("POST ")) {
latch = new CountDownLatch(2);
// 建⽴线程 , ⽤于从内⽹读数据 , 并返回给外⽹
new HttpChannel(clientInputStream, serverOutputStream, latch).start();
} else {
latch = new CountDownLatch(1);
}
// 建⽴线程 , ⽤于从外⽹读数据 , 并返回给内⽹
new HttpChannel(serverInputStream, clientOutputStream, latch).start();
latch.await(120, TimeUnit.SECONDS);
IOUtils.close(serverInputStream, serverOutputStream, server, clientInputStream, clientOutputStream, client);
System.out.println("请求地址:" + clientInputString + ",耗时:" + (System.currentTimeMillis() - createTime) + "ms");        }
/**
* 处理连接请求
*
* @return
*/
private void doConnect() throws IOException, InterruptedException {
String ack = "HTTP/1.0 200 Connection established\r\n";
ack = ack + "Proxy-agent: proxy\r\n\r\n";
clientOutputStream.Bytes());
clientOutputStream.flush();
final CountDownLatch latch = new CountDownLatch(2);
// 建⽴线程 , ⽤于从外⽹读数据 , 并返回给内⽹
new HttpChannel(serverInputStream, clientOutputStream, latch).start();
// 建⽴线程 , ⽤于从内⽹读数据 , 并返回给外⽹
new HttpChannel(clientInputStream, serverOutputStream, latch).start();
latch.await(120, TimeUnit.SECONDS);
IOUtils.close(serverInputStream, serverOutputStream, server, clientInputStream, clientOutputStream, client);
}
}
/**
* 流通道处理线程
*/
private static class HttpChannel extends Thread {
private final CountDownLatch countDownLatch;
private final DataInputStream in;
private final DataOutputStream out;
public HttpChannel(DataInputStream in, DataOutputStream out, CountDownLatch countDownLatch) {
this.in = in;
this.out = out;
}
@Override
public void run() {
byte buf[] = new byte[10240];
try {
while ((len = in.read(buf, 0, buf.length)) != -1) {                    out.write(buf, 0, len);
out.flush();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
IOUtils.close(in, out);
}
}
}
/**
* 流⼯具类
*/
private static class IOUtils {
/**
* 关闭所有流
*/
private static void closeables) {
if (closeables != null) {
for (int i = 0; i < closeables.length; i++) {
if (closeables[i] != null) {
try {
closeables[i].close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。