计算机网络:Socket编程-实现HTTP服务

1、目标

  • 不用框架利用Socket编程实现一个HTTP服务框架

2、线程模型

  • 图示: 线程模型

1、操作系统接受到外部请求时,会把请求放到Pending Queue里面,慢慢积累,如果 Pending Queue被占满时,这里会发生拒绝请求;

2、某一时刻某个线程会触发Accept的系统调用,Accept的系统调用会从Pending Queue拿出一个请求,然后在内核空间形成一个Socket文件,Socket文件会形成资源的一个句柄对应这个文件,派发线程一直循环,不断的Accept将每个文件形成FD(Socket,用来操作文件资源的);

3、将FD派发给工作线程,工作线程读取Socket中的内容,进行处理后,再给用户返回信息,返回时工作线程直接在Socket写入信息,不需要原路返回了;

4、内核监听到Socket的写入信息,然后再把信息返回给请求方。

  • 过程:

1(用户请求)-> 2(Pending Queue收集)-> 3、4、5(线程触发Accept,内核从Pending Queue获取一个请求,形成一个Socket文件,拿到文件句柄)-> 6(线程将获取到的Socket派发到工作线程)-> 7(工作线程先读取4中文件内容,处理完请求后将相关信息直接写入到4中文件中,)-> 8(内核监听到Socket文件写入信息然后再返回给请求方)

3、代码实现(简单实现)

  • HttpServer代码
package com.hh.http;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 简单版
 *
 * @author hang.yuan 2022/3/8 17:58
 */
public class HttpServer {

    public static void main(String[] args) throws IOException {
        ServerSocket socketServer = new ServerSocket(8000);

        //main Thread
        while (true){
            // Blocking ...
            // Thread --> Sleep --> Other Threads
            Socket socket = socketServer.accept();
            System.out.println("socket created");

            InputStream inputStream = new DataInputStream(socket.getInputStream());
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));

            StringBuilder requestBuilder = new StringBuilder();

            String line = "";

            while (true){
                line = bufferedReader.readLine();
                if(line ==null || line.isEmpty()){
                    break;
                }
                requestBuilder.append(line+"\n");
            }
            String request = requestBuilder.toString();
            System.out.println(request);

            BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            bufferedWriter.write("HTTP/1.1 200 ok\n\nhello word!\n");
            bufferedWriter.flush();
            socket.close();
        }
    }
}
  • 测试: 测试

  • 结果:
    测试结果