Java 实现轻量型 HTTP 代理服务器示例

纸上星河
纸上星河
发布时间:2026-10-13| 4人浏览过
原创

如何利用原生 Java 快速搭建一个简单的 HTTP 代理服务?本方案通过 java.net 包中的套接字(Socket)技术,实现了连接监听、HTTP 头解析及数据流中转功能,无需任何第三方库即可运行。

结果与目标

我们的目标是构建一个极简的 HTTP 代理,它具备以下能力: 1. 在指定端口监听传入的 HTTP 请求。 2. 解析请求头以获取目标地址(Host Header)。 3. 建立与目标服务器的新连接,并双向转发客户端与服务端之间的数据。 4. 使用独立线程处理每个会话,以支持并发访问。

准备条件

  • 开发环境:安装 JDK 8 或更高版本。
  • 核心类依赖:java.io 用于 I/O 操作,java.net 用于网络连接,java.util.concurrent(隐含在线程中)用于并发控制。
  • 编译工具:命令行 javac 或任何 IDE(如 IntelliJ IDEA, Eclipse)。

真实操作顺序

第1步:设置主服务监听入口

目的:创建一个后台守护线程,持续监听特定端口等待客户端连接。
入口:HttpProxy 类的构造方法与静态内部类 HTTPSession。
动作:
1. 实例化 ServerSocket 并绑定到配置端口(默认 8580)。

myServerSocket = new ServerSocket(myTcpPort);

2. 启动一个守护线程,循环调用 myServerSocket.accept() 阻塞等待连接。

new Thread(new Runnable() {
    public void run() {
        try {
            while (true)
                new HTTPSession(myServerSocket.accept());
        } catch (IOException ioe) { /* 忽略 */ }
    }
}).start();

3. 将主线程设置为 Daemon 模式,确保服务随 JVM 退出而终止。

第2步:解析 HTTP 请求头部

目的:从原始字节流中识别出 HTTP 协议头部的结束位置,并提取目标主机地址。
入口:findHeaderEnd 方法。
动作:
1. 读取客户端输入流的数据到缓冲区(Buffer)。由于 TCP 是流式传输,HTTP 头部可能跨越多个数据包,需循环读取直到找到尾部标记。

// 读取数据并寻找 \r\n\r\n 标记
while (read > 0) {
    rlen += read;
    splitbyte = findHeaderEnd(buf, rlen);
    if (splitbyte > 0) break;
    read = is.read(buf, rlen, bufsize - rlen);
}

2. 使用 BufferedReader 解析文本头部,查找 Host: 字段。

if (string.toLowerCase().startsWith("host:")) {
    host.host = string;
    // ... 处理标志位
}

第3步:计算目标服务器地址

目的:从 Host 头部字符串中拆解 IP/域名和端口号。
入口:Host.cal() 方法。
动作:
1. 定位冒号位置以确定分隔符。若存在冒号,则截取前部分为地址,后部分转为整数作为端口;若不存在,默认端口设为 80。

if (next == -1) {
    port = 80;
    address = host.substring(start + 2);
} else {
    address = host.substring(start + 2, next);
    port = Integer.valueOf(host.substring(next + 1));
}

第4步:建立代理连接并双向管道传输

目的:将客户端的请求转发给真正的目标服务器,并将响应回传给客户端。
入口:pipe() 方法。
动作:
1. 实例化指向目标地址的新 Socket,并设置超时时间(setSoTimeout(3000))以防止长期挂起。

Socket socket = new Socket(host.address, host.port);
socket.setSoTimeout(3000);

2. 将解析出的头部写入目标连接。

os.write(request, 0, requestLen);

3. 进入轮询循环:读取目标服务器的响应并立即写回客户端,同时检查是否有新的客户端请求需要继续转发。一旦任一端关闭或发生异常,则清理资源。

第5步:启动服务

目的:在本地环境中启动代理程序。
入口:main() 方法。
动作:
1. 创建 HttpProxy 实例并指定监听端口。

new HttpProxy(8580);

2. 主线程通过 System.in.read() 保持存活,按回车键可触发 stop() 方法关闭服务端。

完成判断

当控制台输出 start! 且没有报错时,代理已在 8580 端口就绪。您可以通过浏览器或 curl 工具,将代理服务器设置为本机 IP 和端口 8580,此时请求将被正确转发。注意:此示例主要演示 HTTP 透明代理的基础逻辑,生产环境建议使用 Apache HttpClient、Netty 等成熟框架以应对复杂的头部处理和 SSL/TLS 终端问题。

简要总结

以上就是利用 Java 原生 Socket 实现轻量型 HTTP 代理服务器的详细内容,更多关于 Java 网络编程及本地部署的资料请关注本站其它相关文章!

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。