首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 手寫 HTTP Web 伺服器:從協定原理到多線程實作

     編輯:Java 相關知識

HTTP 協定核心流程

Web 伺服器基於 Client/Server 模型,透過 HTTP 協定(基於 TCP/IP)通訊。核心四步驟:

  1. 連線建立:瀏覽器與伺服器建立 TCP 連線(Socket)
  2. 請求發送:瀏覽器發送 HTTP 請求(如 GET /index.html HTTP/1.0)
  3. 回應處理:伺服器解析請求、讀取檔案、回傳 HTTP 標頭與內容
  4. 連線關閉:雙方釋放 Socket 資源

HTTP 回應標頭關鍵欄位

HTTP/1.0 200 OK           // 狀態行:版本、狀態碼、原因片語
MIME_Version: 1.0         // MIME 版本
Content_Type: text/html   // 內容類型(MIME Type)
Content_Length: 1234      // 實體內容長度(位元組)
                          // 空行分隔標頭與實體
<html>...</html>         // 實體內容

多線程 Web 伺服器完整實作

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

public class WebServer {
    public static void main(String[] args) throws IOException {
        int port = 8080;
        ServerSocket server = new ServerSocket(port);
        System.out.println("Web Server listening on port " + port);
        
        int counter = 1;
        while (true) {
            Socket client = server.accept();
            new ConnectionThread(client, counter++).start();
        }
    }
}

class ConnectionThread extends Thread {
    private Socket client;
    private int id;
    
    public ConnectionThread(Socket client, int id) {
        this.client = client;
        this.id = id;
    }
    
    public void run() {
        try {
            PrintStream out = new PrintStream(client.getOutputStream());
            DataInputStream in = new DataInputStream(client.getInputStream());
            
            String requestLine = in.readLine(); // 讀取請求行
            System.out.println("Request " + id + ": " + requestLine);
            
            if (isGetRequest(requestLine)) {
                String filename = extractFilename(requestLine);
                File file = new File(filename);
                
                if (file.exists() && file.isFile()) {
                    sendFile(out, file);
                } else {
                    send404(out);
                }
            }
            
            client.close();
        } catch (IOException e) {
            System.err.println("Connection " + id + " error: " + e);
        }
    }
    
    private boolean isGetRequest(String line) {
        return line != null && line.length() > 3 && line.substring(0, 3).equalsIgnoreCase("GET");
    }
    
    private String extractFilename(String line) {
        int firstSpace = line.indexOf(' ');
        int secondSpace = line.indexOf(' ', firstSpace + 1);
        String path = line.substring(firstSpace + 1, secondSpace);
        if (path.startsWith("/")) path = path.substring(1);
        return path.isEmpty() ? "index.html" : path;
    }
    
    private void sendFile(PrintStream out, File file) throws IOException {
        out.println("HTTP/1.0 200 OK");
        out.println("MIME_Version: 1.0");
        out.println("Content_Type: text/html");
        out.println("Content_Length: " + file.length());
        out.println(); // 關鍵空行
        
        byte[] buffer = new byte[(int) file.length()];
        new DataInputStream(new FileInputStream(file)).readFully(buffer);
        out.write(buffer);
        out.flush();
    }
    
    private void send404(PrintStream out) {
        String body = "404 Not Found"
                    + "

Error 404 - File Not Found

"; out.println("HTTP/1.0 404 Not Found"); out.println("Content_Type: text/html"); out.println("Content_Length: " + body.length()); out.println(); out.println(body); out.flush(); } }

測試與驗證

  1. 編譯:javac WebServer.java
  2. 準備 index.html 置於同目錄
  3. 啟動:java WebServer
  4. 瀏覽器訪問:https://localhost:8080/index.html

功能擴充路線圖

  • MIME 型別映射:依副檔名動態設定 Content-Type
  • 目錄瀏覽:無 index.html 時列出目錄內容
  • POST 支援:解析 Content-Length 讀取請求實體
  • 靜態資源快取:ETag/Last-Modified 搭配 304 Not Modified
  • SSL/HTTPS:升級 SSLServerSocket 支援加密傳輸
  • NIO 非阻塞:Selector + ServerSocketChannel 處理高併發
  • 虛擬主機:解析 Host 標頭支援多域名

生產級考量

手寫伺服器適合教學與嵌入式場景。生產環境建議使用成熟方案:Jetty、Undertow、Tomcat、Netty 等,提供完整 Servlet 規範支援、連線池、安全性、監控、熱部署等企業級特性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved