天天看點

java使用socket實作簡易多線程web伺服器

通過Socket實作一個簡易的web伺服器,通過浏覽器發起請求,服務端對請求做簡單的核驗,将準備好的html資源傳回給浏覽器,完成一次通路

手寫簡易"TomCat"伺服器:

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;

/*
    自定義伺服器
 */
public class Server {
    public static void main(String[] args) throws IOException {
        ServerSocket ss = new ServerSocket(8080); // 監聽指定端口
        System.out.println("server is running...");
        while (true){
            Socket sock = ss.accept();
            System.out.println("connected from " + sock.getRemoteSocketAddress());
            Thread t = new Handler(sock);
            t.start();
        }
    }
}
//指定一個線程處理一次http請求
class Handler extends Thread {
    Socket sock;
    public Handler(Socket sock) {
        this.sock = sock;
    }
    public void run() {
        try (InputStream input = this.sock.getInputStream()) {
            try (OutputStream output = this.sock.getOutputStream()) {
                handle(input, output);
            }
        } catch (Exception e) {
            try {
                this.sock.close();
            } catch (IOException ioe) {
            }
            System.out.println("client disconnected.");
        }
    }

    private void handle(InputStream input, OutputStream output) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8));
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(output, StandardCharsets.UTF_8));
        // 讀取HTTP請求:
        boolean requestOk = false;

        //讀取http請求的資料
        String first = reader.readLine();
        if (first.startsWith("GET / HTTP/1.")) {
            requestOk = true;
        }
        for (;;) {
            String header = reader.readLine();
            if (header.isEmpty()) { // 讀取到空行時, HTTP Header讀取完畢
                break;
            }
            System.out.println(header);
        }
        System.out.println(requestOk ? "Response OK" : "Response Error");
        if (!requestOk) {
            // 發送錯誤響應:
            writer.write("HTTP/1.0 404 Not Found\r\n");
            writer.write("Content-Length: 0\r\n");
            writer.write("\r\n");
            writer.flush();
        } else {
            // 發送成功響應:
            //讀取html檔案,轉換為字元串
            BufferedReader br = new BufferedReader(new FileReader("F:\\填寫html資源路徑\\index.html"));
            StringBuilder data = new StringBuilder();
            String line = null;
            while ((line = br.readLine()) != null){
                data.append(line);
            }
            br.close();
            int length = data.toString().getBytes(StandardCharsets.UTF_8).length;
            //将響應行寫出
            writer.write("HTTP/1.1 200 OK\r\n");
            //響應頭
            writer.write("Connection: keep-alive\r\n");
            writer.write("Content-Type: text/html\r\n");
            writer.write("Content-Length: " + length + "\r\n");
            writer.write("\r\n"); // 空行辨別Header和Body的分隔
            //響應體資料
            writer.write(data.toString());
            writer.flush();
        }
    }
}

           

運作代碼,通過浏覽器通路 http://localhost:8080/

已經成功通路到了我們指定的html頁面

java使用socket實作簡易多線程web伺服器

在idea的控制台上也成功列印了http請求的資訊

java使用socket實作簡易多線程web伺服器