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

從零構建簡易多線程 HTTP 伺服器:Java 實作指南

     編輯:Java 相關知識

簡介

在網路程式設計的學習歷程中,親手打造一個 HTTP 伺服器是理解網路協議與多線程處理的最佳切入點。本文將帶領你逐步實作一個基於 Java Socket 的多線程 HTTP 伺服器,並針對核心邏輯進行深度解析。雖然這是一個教學級別的簡易實作,但它涵蓋了伺服器端處理高併發請求的核心架構:ServerSocket 監聽、accept() 阻塞等待連線、為每個連線獨立啟動執行緒處理業務邏輯。

核心架構設計

伺服器主類別 HttpServer 負責初始化通訊埠(預設 8888)並進入無限迴圈監聽客戶端連線。每當有新連線建立,主執行緒便將 Socket 物件交給內部類別 ProcessThread 處理,隨即返回繼續監聽下一個連線。這種「一連線一執行緒」的模型雖然簡單直觀,但在高併發場景下會因頻繁建立/銷毀執行緒而造成效能瓶頸,後續可優化為執行緒池模式。

請求處理流程詳解

ProcessThread 繼承 Thread,其 run() 方法完整呈現了 HTTP 請求-回應週期:

  1. 讀取請求頭:透過 BufferedReader 逐行讀取輸入流,直到遇到空行(HTTP 協議規定請求頭以雙 CRLF 結束)。
  2. 解析與日誌:本範例僅將請求頭列印至控制台,實際生產環境需解析 Method、URI、Headers 等資訊。
  3. 構建回應:使用 PrintWriter 輸出標準 HTTP 回應,包含狀態行(HTTP/1.0 200 OK)、Content-Type 標頭、空行分隔符,最後輸出 HTML 內容體。
  4. 資源釋放:在 finally 區塊確保關閉 Socket,避免檔案描述符洩漏。

完整原始碼

package thread;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * Threaded Network Server
 * 簡易多線程 HTTP 伺服器示範
 * 採用多線程處理高併發用戶請求
 */
public class HttpServer {
    public static void main(String[] args) {
        HttpServer hs = new HttpServer();
        int i = 1, port = 8888;
        Socket received = null;
        try {
            ServerSocket server = new ServerSocket(port);
            System.out.println("伺服器已啟動,監聽埠口:" + port);
            while (true) {
                received = server.accept();
                if (received != null) {
                    hs.new ProcessThread(i++, received).start();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    class ProcessThread extends Thread {
        private int threadNumber = 0;
        private Socket received = null;

        public ProcessThread(int threadNumber, Socket received) {
            super();
            this.threadNumber = threadNumber;
            this.received = received;
        }

        @Override
        public void run() {
            System.out.println("第 " + threadNumber + " 個處理執行緒啟動了……");
            if (received != null) {
                try {
                    System.out.println("連接用戶的地址:" + received.getInetAddress().getHostAddress());
                    InputStream in = received.getInputStream();
                    BufferedReader reader = new BufferedReader(new InputStreamReader(in));
                    String line = reader.readLine();
                    while (line != null && !line.equals("")) {
                        System.out.println(line);
                        line = reader.readLine();
                    }
                    OutputStream out = received.getOutputStream();
                    PrintWriter writer = new PrintWriter(out, true);
                    String html = "<html><head><title></title></head><body><h1>收到!</h1></body></html>";
                    writer.println("HTTP/1.0 200 OK");
                    writer.println("Content-Type:text/html;charset=GBK");
                    writer.println(); // 空行結束 Header
                    writer.println(html);
                    writer.flush();
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    try {
                        received.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

執行與驗證

編譯並執行 HttpServer 後,瀏覽器訪問 https://localhost:8888/ 即可看到「收到!」的回應頁面。控制台將輸出執行緒啟動資訊、客戶端 IP 及完整的 HTTP 請求頭,方便觀察協議細節。

後續擴展方向

作者在原文中規劃了四大演進方向,也是從教學版邁向生產級的關鍵步驟:

  • 支援 POST 請求:需解析 Content-Length 並讀取請求體。
  • 二進制流傳輸:處理圖片、檔案下載等非文本資源,需使用 InputStream/OutputStream 而非 Reader/Writer。
  • 執行緒池:引入 ExecutorService 替代顯式 new Thread(),控制併發數量並複用執行緒。
  • NIO 非阻塞模型:採用 Selector + SocketChannel 實現單執行緒多路複用,大幅提升併發上限。

總結

這個簡易伺服器雖然功能極簡,卻完整展示了 Java 網路程式設計的基石:Socket 通訊、多線程併發、HTTP 協議解析與回應構建。理解這些基礎機制,才能在後續學習 Netty、Tomcat 等成熟框架時,看透其底層運作原理,做出更合理的架構選型與效能調優。

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