第一章:实现基础 HTTP 服务器-MiniTomcat

在本章中,我们将从零开始编写一个简单的 HTTP 服务器。该服务器的核心功能是监听指定端口,接收客户端的 HTTP 请求,并返回相应的 HTTP 响应。我们将利用 Java 的 ServerSocket 类实现网络监听,并通过 InputStreamOutputStream 处理请求与响应数据。

1.1 创建基础 HTTP 服务器

我们的目标是构建一个能够监听客户端请求并返回简单响应的 HTTP 服务器。实现过程主要分为以下三个步骤:

  1. 创建 ServerSocket 监听端口:使用 ServerSocket 类创建服务器套接字,监听指定端口。
  2. 接受客户端连接并接收请求:通过 Socket 接受客户端连接,并从输入流中读取 HTTP 请求。
  3. 发送 HTTP 响应:构建标准的 HTTP 响应报文,并通过输出流发送给客户端。

1.2 实现代码

以下是 SimpleHttpServer 的完整实现代码:

import java.io.*;
import java.net.*;

public class SimpleHttpServer {
    private static final int PORT = 8080;

    public static void main(String[] args) {
        try (ServerSocket serverSocket = new ServerSocket(PORT)) {
            System.out.println("HTTP Server is running on port " + PORT);

            while (true) {
                // 接受客户端连接
                Socket clientSocket = serverSocket.accept();
                System.out.println("New connection from " + clientSocket.getInetAddress());

                // 获取输入流,读取客户端请求
                InputStream inputStream = clientSocket.getInputStream();
                BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
                String requestLine = reader.readLine();
                if (requestLine != null) {
                    System.out.println("Request: " + requestLine);
                }

                // 构建一个简单的 HTTP 响应
                OutputStream outputStream = clientSocket.getOutputStream();
                PrintWriter writer = new PrintWriter(outputStream, true);
                writer.println("HTTP/1.1 200 OK");
                writer.println("Content-Type: text/html; charset=UTF-8");
                writer.println();  // 空行,表示响应头结束
                writer.println("<html>");
                writer.println("<head><title>Simple HTTP Server</title></head>");
                writer.println("<body><h1>Hello, World!</h1></body>");
                writer.println("</html>");

                // 关闭连接
                clientSocket.close();
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

1.3 代码解析

  1. 创建 ServerSocket 实例

    ServerSocket serverSocket = new ServerSocket(PORT);

    这行代码创建了一个监听指定端口(本例为 8080)的 ServerSocket 实例。ServerSocket 是 Java 提供的用于监听客户端连接的核心类。

  2. 接受客户端连接

    Socket clientSocket = serverSocket.accept();

    调用 accept() 方法后,服务器会阻塞并等待客户端连接。一旦连接建立,该方法返回一个 Socket 对象,代表与客户端的通信链路。

  3. 读取 HTTP 请求

    BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
    String requestLine = reader.readLine();

    通过输入流读取 HTTP 请求的第一行(请求行),例如 GET / HTTP/1.1。这是 HTTP 请求的基础信息,包含请求方法、资源路径和 HTTP 协议版本。

  4. 发送 HTTP 响应

    PrintWriter writer = new PrintWriter(outputStream, true);
    writer.println("HTTP/1.1 200 OK");
    writer.println("Content-Type: text/html; charset=UTF-8");
    writer.println();
    writer.println("<html>");
    writer.println("<head><title>Simple HTTP Server</title></head>");
    writer.println("<body><h1>Hello, World!</h1></body>");
    writer.println("</html>");

    此处构建了一个简单的 HTTP 响应。首先发送状态行(如 HTTP/1.1 200 OK),紧接着发送响应头(如 Content-Type)。空行用于标识响应头结束,随后是响应体(一个显示 "Hello, World!" 的 HTML 页面)。

  5. 关闭连接

    clientSocket.close();

    每次请求处理完毕后,关闭与客户端的 Socket 连接,释放资源。

1.4 测试 HTTP 服务器

  1. 编译并运行 SimpleHttpServer 类。
  2. 在浏览器中访问 http://localhost:8080,页面应显示 "Hello, World!"。
  3. 也可使用 curl 命令在终端测试:

    curl http://localhost:8080

1.5 总结

通过本章,我们实现了一个最基础的 HTTP 服务器,能够监听客户端请求并返回静态 HTML 页面。虽然该服务器功能简单,但它构成了后续扩展功能(如静态文件支持、Servlet 容器等)的核心框架。

在下一章中,我们将开始深入解析 HTTP 请求,并实现对静态文件的支持。


参考资料