日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

實現自定義HTTP服務器

作者:hotChenSun 更新時間: 2022-07-22 編程語言

你需要了解基本Java網絡編程知識。

HTTP請求組成部分

? 1. 請求行

? ? ?請求行包含三塊內容,分別是 GET[請求方式] /[請求URL路徑] HTTP/1.1[HTTP協議及版本]

? 2. 請求頭

? ? ?第二行開始,格式為key: value形式

? ? ?常見的HTTP請求頭有:

? ? ?Host: 表示請求的主機名
? ? ?User-Agent: 瀏覽器版本,例如Chrome瀏覽器的標識類似Mozilla/5.0 ...Chrome/79,IE瀏覽器的標識類似Mozilla/5.0 (Windows NT ...)like Gecko;
? ? ?Accept:表示瀏覽器能接收的資源類型,如text/*,image/*或者*/*表示所有;
? ? ?Accept-Language:表示瀏覽器偏好的語言,服務器可以據此返回不同語言的網頁;
? ? ?Accept-Encoding:表示瀏覽器可以支持的壓縮類型,例如gzip, deflate等。

? 3. 請求體

? ? ?有一空行隔開? ? ?post請求方式時,瀏覽器傳輸的數據(表單數據)

HTTP響應組成部分

響應數據包:

  1. 響應行

    包含三塊內容,分別是 HTTP/1.1[HTTP協議及版本] 200[響應狀態碼] ok[狀態碼的描述]

  2. 響應頭

    第二行開始,格式為key:value形式

常見的HTTP響應頭有:

Content-Type:表示該響應內容的類型,例如text/html,image/jpeg;
Content-Length:表示該響應內容的長度(字節數);
Content-Encoding:表示該響應壓縮算法,例如gzip;
Cache-Control:指示客戶端應如何緩存,例如max-age=300表示可以最多緩存300秒

????????3.響應體

????????最后一部分。存放響應數據

? ? ? ? 可以存放html格式數據,<html>...</html>這部分內容就是響應體,它和響應頭之間有一個空行隔開。

HTTP常見響應碼

關于響應狀態碼,我們先主要認識三個狀態碼,其余的等后期用到了再去掌握:

  • 200 ok 客戶端請求成功

  • 404 Not Found 請求資源不存在

  • 500 Internal Server Error 服務端發生不可預期的錯誤

好了,我們可以基于java套接字實現一個簡單的HTTP服務器了。

/*
    自定義服務器
 */
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();
        }
    }
}

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;
        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("http/html/a.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();
        }
    }
}

原文鏈接:https://blog.csdn.net/m0_67338583/article/details/125919153

欄目分類
最近更新