计算机网络: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();
}
}
}
测试:
结果: