🔥博客主页: 【小扳_-CSDN博客】
❤感谢大家点赞👍收藏⭐评论✍
文章目录
1.0 HTTP 协议概述
HTTP(Hypertext Transfer Protocol)是一种用于传输超文本的应用层协议。它是 Web 上数据传输的基础,用于在客户端和服务器之间传输数据。HTTP 是一个无状态的协议,即每个请求都是独立的,服务器不会保存任何关于客户端的状态信息。
HTTP 协议基于请求-响应模型,客户端发送请求给服务器,服务器处理请求并返回响应。请求由请求行、请求头和请求体组成,响应由状态行、响应头和响应体组成。
HTTP 协议使用 TCP 作为传输层协议,通常在 80 端口上进行通信。它支持多种请求方法,如 GET、POST、PUT、DELETE 等,用于不同的操作。HTTP 还支持状态码来表示请求的处理结果,如 200 表示成功,404 表示未找到等。
特点:
1)基于 TCP 协议:面向连接,安全。
2)基于请求-响应模型的:一次请求对应一次响应。
3)HTTP 协议是无状态的协议:对于事务处理没有记忆能力。每次请求-响应都是独立的。缺点:多次请求间不能共享数据。优点:速度快。
2.0 HTTP 请求协议
HTTP 请求协议是客户端向服务器发送请求的格式和规范。一个标准的 HTTP 请求由以下几部分组成:
1)请求行:包含请求方法、请求的 URL 和协议版本。常见的请求方法有 GET、POST、PUT、DELETE 等。
在请求格式中的第一行中包含:
1.1)有发送的请求方法,常见的请求方法有 GET、POST 方法。
1.2)资源路径,访问的资源路径。
1.3)协议版本,比如 HTTP/1.1
举个例子:
这个 HTTP 协议中用到了 GET 请求的方法,还有资源路劲、版本为 HTTP/1.1。
2)请求头:包含一系列的键值对,用于传递请求的元数据信息,如 User-Agent(用户代理)、Host(主机名)、Content-Type(内容类型)等。
常见的数据信息:
2.1)Host:请求的主机名。
2.2)User-Agent:浏览器版本。
2.3)Accept:表示浏览器能接受的资源类型,如 text/*,image/* 或者 */* 表示所有;
2.4)Accept-Language:表示浏览器偏好的语言,服务器可以据此返回不同语言的网页。
2.5)Accept-Encoding:表示浏览器可以支持的压缩类型,例如 gzip,deflate 等。
2.6)Content-Type:请求主题的数据类型。
2.7)Content-Length:请求主体的大小(单位:字节)。
举个例子:
3)空行:请求头和请求体之间需要有一个空行来分隔。
4)请求体:可选的,通常用于传输请求的数据,如POST请求中的表单数据、上传文件等。
4.1)请求方式-GET:请求参数在请求行中,没有请求体,如:/brand/findAll?name=OPPO&status=1。请求参数而是在请求行中的资源路径后加上 ? 和 请求参数。GET 请求大小是有限制的。
4.2)请求方法-POST:请求参数在请求体中,POST 请求大小是没有限制的。
举个例子:
POST /api/users HTTP/1.1 Host: api.example.com User-Agent: Mozilla/5.0 Content-Type: application/json Authorization: Bearer abcdef1234567890 { "name": "John Doe", "email": "johndoe@example.com", "age": 30 }
在这个示例中,请求方法是 POST,请求的 URL 是 /api/users ,协议版本是 HTTP/1.1。请求头包含 Host、User-Agent、Content-Type 和 Authorization 等信息。请求体是一个 JSON 格式的数据,包含了用户的姓名、邮箱和年龄信息。
2.1 请求方式的具体体现
HTML 代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>测试</title> </head> <body> <form action="" method="get"> 名字:<input type="text" name="name"> <br> 密码:<input type="password" name="password"> <br> <input type="submit" value="利用GET方法提交"> </form> <br><br> <form action="" method="post"> 名字:<input type="text" name="name"> <br> 密码:<input type="password" name="password"> <br> <input type="submit" value="利用POST方法提交"> </form> </body> </html>
运行页面:
1)利用 DET 方法提交结果:
提交后,请求参数就会在资源路径中出现:
2)利用 POST 方法提交结果:
提交后,请求参数会在请求体中出现:
分析视图:
3.0 HTTP 响应协议
HTTP 响应协议是一种用于在客户端和服务器之间传输数据的协议。它定义了服务器对客户端请求的响应格式和规范。
HTTP 响应协议由状态行、响应头、空行和响应体组成。
状态行包含了响应的状态码和描述,响应头包含了响应的元数据信息,空行用于分隔响应头和响应体,响应体包含了实际的响应数据。
举个例子:
3.1 常见的状态码及描述
1)以 “1xx” 开头的状态码:响应中-临时状态码,表示请求已经接受,告诉客户端应该继续请求或者如果它已经完成则忽略它。
2)以 “2xx” 开头的状态码:成功-表示请求已经被成功接收,处理已完成。
3)以 “3xx” 开头的状态码:重定向-重定向到其他地方;让客户端再发起一次请求以完成整个处理。
4)以 “4xx” 开头的状态码:客户端错误-处理发生错误,责任在客户端。如:请求了不存在的资源,客户端未被授权、禁止访问等。
5)以 “5xx” 开头的状态码:服务器错误-处理发生错误,责任在服务端。如:程序抛异常等。
具体的状态码:
3.2 常见的响应头
1)Content-Type:表示该响应内容的类型,例如 text/html,application/json 。
2)Content-Length:表示该响应内容的长度(字节数)。
3)Content-Encoding:表示该响应压缩算法,例如 gzip 。
4)Cache-Control:指示客户端如何缓存,例如 max-age=300 表示可以最多缓存 300 秒。
5)set-Cookie:告诉浏览器为当前页面所在的域设置 cookie 。
4.0 HTTP 协议解析
由于浏览器已经自带了 HTTP 协议解析,所以,主要是对服务器端开发 HTTP 协议解析。
4.1 简单实现服务器响应客户端请求
客户端发起一次请求,服务器就会响应一次,大致的解析过程:
先客户端与服务器建立连接,客户端发送一次请求。接着,服务端接收到来自客户端发送的请求,先验证发送的请求行是否正确,接着响应客户端请求的数据。
代码如下:
import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; public class Hello { public static void main(String[] args) throws IOException { ServerSocket serverSocket = new ServerSocket(8888); while (true){ //管道接通 Socket socket = serverSocket.accept(); Thread thread = new MyThread(socket); thread.start(); System.out.println(thread.getName() + " 正在执行!!!"); } } }
import java.io.*; import java.net.Socket; public class MyThread extends Thread{ Socket socket; public MyThread (Socket socket){ this.socket = socket; } @Override public void run() { try( OutputStream os = socket.getOutputStream(); InputStream is = socket.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(is)); BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os)); ){ //先接受客户端请求过来的数据 String s; while (!(s = reader.readLine()).isEmpty()){ System.out.println(s); } StringBuilder stringBuilder = new StringBuilder(); //读取数据 readData(stringBuilder); //接着再返回数据 writer.write("HTTP/1.1 200 OK\r\n"); writer.write("Content-Type:text/html;charset=UTF-8\r\n"); writer.write("\r\n"); writer.write(stringBuilder.toString()); }catch (Exception e){ e.printStackTrace(); } } public void readData(StringBuilder stringBuilder){ try( InputStream inputStream = new FileInputStream("D:\\software\\code\\2023_java\\2023_java_code\\code_24_5_8\\src\\main\\java\\org\\example\\Demo\\response.html"); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); ){ while (true){ String s = reader.readLine(); if ( s == null || s.isEmpty()){ break; } stringBuilder.append(s); } }catch (Exception e){ e.printStackTrace(); } } }
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>测试</title> </head> <body> <table border="1px" cellspacing="0px" align="center"> <tr> <th>姓名</th> <th>性别</th> <th>ID</th> </tr> <tr> <td>小扳手</td> <td>男</td> <td>01</td> </tr> <tr> <td>小童</td> <td>女</td> <td>02</td> </tr> <tr> <td>小落</td> <td>男</td> <td>03</td> </tr> <tr> <td>小益</td> <td>女</td> <td>04</td> </tr> </table> </body> </html>
运行结果:
访问当前服务器端口号 8888 :
需要注意的是:解析 HTTP 协议代码可远远不止以上这些,以上这些代码只是了解服务端大致解析 HTTP 协议的简单流程仅此而已,还有很多很多复杂的过程以上代码都没有涉及到。
因此得知,程序员手动实现解析 HTTP 协议代码是不现实的。
为了更高效地处理 HTTP 请求,程序员通常会使用现成的 HTTP 服务器框架或库,例如 Node.js 中的 Express 框架、Python 中的 Django 框架等。这些框架和库已经实现了完整的 HTTP 协议解析和处理功能,开发者只需要调用相应的接口来处理请求和响应即可,大大简化了开发过程。