🔥博客主页: 【小扳_-CSDN博客】
❤感谢大家点赞👍收藏⭐评论✍
文章目录
1.0 HTTP 协议概述
2.0 HTTP 请求协议
2.1 请求方式的具体体现
3.0 HTTP 响应协议
3.1 常见的状态码及描述
3.2 常见的响应头
4.0 HTTP 协议解析
4.1 简单实现服务器响应客户端请求
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 协议解析和处理功能,开发者只需要调用相应的接口来处理请求和响应即可,大大简化了开发过程。