Skip to content

Repository files navigation

简易HTTP服务器(SimpleHTTPServer)

基于Java Socket网络编程实现的多线程HTTP服务器,支持GET、POST和HEAD请求方法。

一、项目概述

本项目实现了一个简易但功能完整的HTTP服务器,采用面向对象设计,使用Java Socket网络编程和多线程技术,能够响应浏览器的HTTP请求并返回静态网页文件。

核心特性

  • 多线程处理:使用线程池管理客户端连接,支持多个客户端同时访问
  • HTTP方法支持:支持GET、POST、HEAD三种HTTP请求方法
  • 静态文件服务:支持HTML、CSS、JavaScript、图片等多种文件类型
  • 错误处理:支持400、403、404、405、500等HTTP状态码
  • 安全防护:防止目录遍历攻击(检测..~
  • 日志记录:记录服务器运行日志和访问日志
  • URL解码:支持URL编码(如中文文件名)

技术栈

技术 说明
Java Socket 网络编程,监听端口、接受连接
多线程 ExecutorService线程池,支持并发处理
面向对象 类封装、职责分离、工厂模式
HTTP协议 HTTP/1.1协议的基本实现

二、系统架构

2.1 整体架构

┌─────────────┐     ┌─────────────────┐     ┌──────────────────┐
│   浏览器     │────▶│   HTTP服务器     │────▶│   静态文件       │
│  (客户端)    │◀────│   (服务器端)     │◀────│   (webroot/)     │
└─────────────┘     └─────────────────┘     └──────────────────┘

2.2 类设计

类名 职责 行数
HttpServer 服务器主类,负责启动监听、接受连接、线程池管理 78行
ClientHandler 客户端处理器,实现Runnable接口,处理单个客户端请求 203行
HttpRequest HTTP请求解析器,解析请求行、请求头、请求体 204行
HttpResponse HTTP响应构建器,构建状态行、响应头、响应体 160行
Logger 日志工具类,记录服务器运行日志和访问日志 47行

总代码行数:692行

2.3 请求处理流程

客户端发起请求
    │
    ▼
ServerSocket.accept() 接受连接
    │
    ▼
提交到线程池(ExecutorService)
    │
    ▼
ClientHandler.run() 处理请求
    │
    ├── HttpRequest.parse() 解析请求
    │       ├── 解析请求行(方法、URL、协议版本)
    │       ├── 解析请求头(Content-Length、Host等)
    │       └── 解析请求体(POST数据)
    │
    ├── 根据请求方法分发处理
    │       ├── GET  → handleGet()  → 返回文件内容
    │       ├── POST → handlePost() → 返回POST数据
    │       └── HEAD → handleHead() → 返回响应头
    │
    ├── HttpResponse.send() 发送响应
    │       ├── 构建状态行(HTTP/1.1 200 OK)
    │       ├── 构建响应头(Content-Type、Content-Length)
    │       └── 发送响应体(HTML内容)
    │
    └── 关闭连接

三、功能说明

3.1 GET请求处理

根据客户端请求的URL,从webroot/目录下查找并返回对应的静态文件。

支持的文件类型:

文件类型 Content-Type
.html / .htm text/html
.css text/css
.js application/javascript
.jpg / .jpeg image/jpeg
.png image/png
.gif image/gif
其他 application/octet-stream

示例:

# 访问首页
curl http://localhost:8080/

# 访问指定页面
curl http://localhost:8080/index.html

3.2 POST请求处理

接收客户端发送的POST数据,并返回收到的数据。

示例:

# 发送POST请求
curl -X POST -d "name=张三&message=Hello" http://localhost:8080/submit

# 返回结果
<html><body><h1>POST数据已收到</h1><p>name=张三&message=Hello</p></body></html>

3.3 HEAD请求处理

与GET请求类似,但只返回响应头,不返回响应体。常用于检查资源是否存在。

示例:

curl -I http://localhost:8080/

返回结果:

HTTP/1.1 200 OK
Server: SimpleHTTPServer/1.0
Connection: close
Content-Length: 8948
Date: Thu Jun 26 02:49:11 CST 2026
Content-Type: text/html

3.4 错误处理

状态码 说明 触发条件
200 OK 请求成功 文件存在或POST处理成功
400 Bad Request 请求格式错误 无法解析HTTP请求
403 Forbidden 拒绝访问 请求包含..~(目录遍历)
404 Not Found 资源不存在 请求的文件不存在
405 Method Not Allowed 方法不允许 使用了不支持的HTTP方法
500 Internal Server Error 服务器内部错误 服务器处理异常

3.5 安全防护

  • 目录遍历防护:检测URL中的..~,防止访问webroot目录之外的文件
  • 路径规范化:使用getCanonicalPath()获取文件真实路径,确保文件在webroot目录内

3.6 日志记录

服务器会记录以下日志:

[2026-06-26 02:25:14] [INFO] ========================================
[2026-06-26 02:25:14] [INFO] 简易HTTP服务器启动成功
[2026-06-26 02:25:14] [INFO] 监听端口: 8080
[2026-06-26 02:25:14] [INFO] 访问地址: http://localhost:8080/
[2026-06-26 02:25:14] [INFO] ========================================
[2026-06-26 02:48:46] [INFO] 新连接: /127.0.0.1:54312
[2026-06-26 02:48:46] /127.0.0.1:54312 POST /submit 200

四、环境要求

  • Java JDK:8 或更高版本(已测试 JDK 17)
  • 操作系统:Windows / Linux / macOS
  • 磁盘空间:约 10MB

五、快速开始

5.1 编译项目

# 方式一:使用编译脚本
chmod +x build.sh
./build.sh

# 方式二:手动编译
mkdir -p out
javac -d out src/main/java/com/httpserver/*.java

5.2 启动服务器

# 使用默认端口8080
java -cp out com.httpserver.HttpServer

# 指定端口
java -cp out com.httpserver.HttpServer 9090

5.3 访问服务器

在浏览器中访问:

5.4 停止服务器

# 方式一:Ctrl+C(前台运行时)
# 方式二:kill进程
pkill -f 'com.httpserver.HttpServer'

六、功能测试

6.1 测试GET请求

# 测试首页访问
curl -s http://localhost:8080/

# 测试响应头
curl -sI http://localhost:8080/

# 测试指定文件
curl -s http://localhost:8080/index.html

6.2 测试POST请求

# 发送POST数据
curl -s -X POST -d "name=张三&age=20" http://localhost:8080/submit

# 发送JSON数据
curl -s -X POST -H "Content-Type: application/json" -d '{"key":"value"}' http://localhost:8080/submit

6.3 测试错误处理

# 测试404错误(访问不存在的文件)
curl -s http://localhost:8080/nonexistent.html

# 测试目录遍历防护
curl -s http://localhost:8080/../etc/passwd

6.4 使用Python测试

import urllib.request
import urllib.parse

# 测试GET请求
response = urllib.request.urlopen('http://localhost:8080/')
print('GET Status:', response.status)

# 测试POST请求
data = urllib.parse.urlencode({'name': '张三', 'message': 'Hello'}).encode()
req = urllib.request.Request('http://localhost:8080/submit', data=data, method='POST')
with urllib.request.urlopen(req) as response:
    print('POST Status:', response.status)
    print('Body:', response.read().decode())

6.5 测试结果示例

=== 测试GET请求 ===
状态码: 200
响应大小: 8948 字节

=== 测试POST请求 ===
<html><body><h1>POST数据已收到</h1><p>name=张三&message=Hello</p></body></html>

=== 测试HEAD请求 ===
HTTP/1.1 200 OK
Server: SimpleHTTPServer/1.0
Connection: close
Content-Length: 0

=== 测试404错误 ===
状态码: 404

七、项目结构

java/
├── src/
│   └── main/
│       └── java/
│           └── com/
│               └── httpserver/
│                   ├── HttpServer.java      # 服务器主类(78行)
│                   ├── ClientHandler.java   # 客户端处理器(203行)
│                   ├── HttpRequest.java     # HTTP请求解析器(204行)
│                   ├── HttpResponse.java    # HTTP响应构建器(160行)
│                   └── Logger.java          # 日志工具类(47行)
├── webroot/                                 # 静态文件目录
│   └── index.html                           # 默认首页
├── images/                                  # 图表目录
│   ├── class_diagram.mmd                    # 类图(mermaid格式)
│   ├── request_flow.mmd                     # 请求流程图(mermaid格式)
│   └── system_architecture.mmd              # 系统架构图(mermaid格式)
├── out/                                     # 编译输出目录
├── build.sh                                 # 编译脚本
├── package.sh                               # 打包脚本
├── test.sh                                  # 测试脚本
├── MANIFEST.MF                              # JAR打包配置
├── 刘龙灿-报告.md                            # 刘龙灿的课程设计报告
├── 周宇聪-报告.md                            # 周宇聪的课程设计报告
└── README.md                                # 本文件

八、团队分工

成员 负责模块 主要工作
刘龙灿 协议处理模块 HTTP请求解析、HTTP响应构建、服务器主框架、协议处理逻辑
周宇聪 业务处理模块 客户端请求处理、静态文件服务、错误处理、测试页面设计

九、参考资料

  1. HTTP协议规范:https://tools.ietf.org/html/rfc2616
  2. Java Socket编程:https://docs.oracle.com/javase/tutorial/networking/sockets/
  3. Java多线程编程:https://docs.oracle.com/javase/tutorial/essential/concurrency/
  4. Java实现HTTP服务器参考:http://blog.csdn.net/earbao/article/details/16354881
  5. HTTP协议简介:http://zsxxsz.iteye.com/blog/568250
  6. HTTP协议详解:http://www.cnblogs.com/zhijianliutang/archive/2012/09/23/2698860.html

十、常见问题

Q1: 端口被占用怎么办?

# 查看端口占用
lsof -i:8080

# 使用其他端口
java -cp out com.httpserver.HttpServer 9090

Q2: 中文文件名乱码怎么办?

确保HTML文件使用UTF-8编码保存,并在HTML头部指定:

<meta charset="UTF-8">

Q3: 如何添加新的文件类型支持?

ClientHandler.javagetContentType()方法中添加:

} else if (url.endsWith(".pdf")) {
    return "application/pdf";
}

Q4: 如何修改线程池大小?

HttpServer.java中修改:

this.threadPool = Executors.newFixedThreadPool(20); // 改为20

十一、许可证

本项目仅用于课程设计学习,不用于商业用途。

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages