当前位置: 首页 > news >正文

【Linux】应用层协议—HTTP

一、HTTP协议介绍

  1. 请求-响应模型:HTTP (Hyper Text Transfer Protocol) 协议是基于请求和响应的。客户端(如Web浏览器)发送一个HTTP请求到服务器,服务器处理请求后返回一个HTTP响应。

  2. 无状态,无连接协议:HTTP协议本身是无状态的,这意味着每个请求都是独立的,每次请求都需要建立新的连接。服务器不会保存任何关于前一个请求的信息。每次请求都需要包含所有必要的信息。

  3. HTTP 协议通常运行在 TCP 之上,即HTTP 是基于 TCP 实现的应用层协议
  4. HTTP 协议定义了客户端 (如浏览器) 与服务器之间如何通信,用以交换或传输超文本。
    • 超文本:视频、音频、图片、图标、HTML 文件等。

二、URL  URI  URLN

  • URI: 统一资源标识符(Uniform Resource Identifier),用来标识资源的唯一性
  • URN: 统一资源名称(Uniform Resource Name),用名字标识资源
  • URL: 统一资源定位符(Uniform Resource Locator),给互联网上的每一个文件资源都贴上这样一个唯一标签,并且包含了资源位置信息和访问方式浏览器可以通过URL中的文件位置信息找到对应的资源文件。

平常所说的网址就是统一资源定位符 URL (Uniform Resource Lacator) 是因特网的万维网服务程序上用于指定信息位置的表示方法。

URL 的构成部分

  • 协议方案名: 发起请求用到的协议,http:// 表示在请求时需要使用的协议,通常使用的是 HTTP 或 HTTPS 协议
  • 登录信息: 登录认证是用户的信息,有可能包含用户的用户名和密码。大多数的 URL 网址中,已经省略了该部分,转而将登录信息通过其他方案交付给服务器。
    • 例如验证码,扫码。
  • 服务器地址: 访问资源所在的服务器的地址,也就是域名(字符串风格的)。服务器地址 www.example.jp 也叫做域名。域名等价于 IP 地址 URL 中通过域名来映射对应服务器的 IP 地址
    • 浏览器会自动将域名转换成对应服务器的 IP 地址。
    • 可通过ping 域名 得到对应网站的ip

    如:

  • 端口号: 服务器绑定的端口号
  • HTTP 协议和套接字编程都是位于应用层,在进行套接字编程时需要给服务器绑定对应的 IP + port, HTTP 这个应用层协议也需要有明确的端口号。
  • 常见协议所对应的端口号

  •  URL 一般会省略服务器端口号
    • 协议名称与端口号强关联,知名协议的端口号都是固定的。在使用某协议时,该协议实际就在为用户提供服务。
  • IP 地址和端口号缺一个都不可能访问到服务器。平时用的 URL 会省略服务器端口号,但在发起 HTTP 请求时,会自动拼接 80 这个端口号。
  • 发起其他协议请求时也会自动拼接与该协议所对应的端口号
  • 文件路径: 访问资源在目标服务器上的位置信息
    • 带层次的文件路径 /dir/index.htm 表示的是要访问的资源的所在路径,也就是在该主机上唯一的文件资源
    • 从网络上获取资源本质上就是拷贝。从对应服务器中获取资源,并通过网络拿到自己手上。
  • 查询字符串: 查询信息
  • uid=1 表示的是请求服务时额外提供的参数,这些参数通常以键值对的形式呈现,通过 & 分隔。

栗子:在浏览器搜索关键词qq

  • 此处的 q=qq 就代表搜索关键词为qq
  • 片段标识符: 对某些资源信息的描述与补充
  • URL是URI的一种,URL是URI的一种具体表现,包含了资源的位置信息和获取资源的方式
  • URN是URI的一种,用特定命名字标识资源,但不包含访问方式。

三、urlencode和urldecode

         1 .URL 对特殊字符的编码转义

  • / ? : 等这样的字符, 已经被 url 当做特殊意义理解了. 因此这些字符不能随意出现.
    • 比如, 某个参数中需要带有这些特殊字符, 就必须先对特殊字符进行转义.

特殊字符的转义规则

  • 将需要转码的字符转为 16 进制,然后从右到左,取 4 (不足 4 位直接处理),每 2 做一位,前面加上%,编码成%XY 格式

例如:

  • "+" 被转义成了 "%2B"
  • 而urldecode 就是 urlencode 的逆过程;

         2 .为什么要对特殊字符进行编码转义

  • 如果搜索的关键词包含特殊字符,不进行转义的话,这些特殊字符就可能会干扰到当前 URL,导致 URL 的链接出现问题。

          3 .在线解码工具

在线解码工具在线解码工具

四、HTTP 协议的格式

         1 .HTTP 协议的请求格式

  • 请求行:请求方法 + URL + HTTP 版本,这里的 URL 表示的是请求的资源的所在路径。
  • 请求报头:请求的属性,以key:value的形式显示,且用空行分隔每一个属性信息
  • 空行:分隔报头和报文,遇到空行就表示请求报头结束。
  • 请求正文:一般为用户的相关信息或数据,允许为空字符串,如果请求正文存在,则在请求报头中添加一个 content-length 属性来标识请求正文的长度

问题:HTTP协议如何保证报头和有效载荷分离?

  • 当应用层收到一个 HTTP 请求时,需要将该 HTTP 请求的报头与有效载荷进行分离
    • 对于一个 HTTP 请求,报头 = 请求行 + 请求报头;有效载荷 = 请求正文。
  • 可以根通过HTTP 请求中的空行来将报头和有效载荷分离。当服务器收到一个 HTTP 请求报文时,按行读取该报文,如果读取到空行则报头读取完毕
  • 回车 + 换行 = \n,如果连续读取到两个 \n,则说明已将报头读取完毕,剩下的都是有效载荷。
  • 一般还会有Content-Length属性字段来标识正文的长度

问题:服务端如何保证自己读取报头完毕?

  • 循环读取,直到读到空行,就说明报头信息读取完毕 

         2 .HTTP 请求的代码

我们可以编写一个简单的基于TCP协议的服务器,并且通过以浏览器作为客户端,对服务器发起请求,并把请求部分打印下来,代码如下:

#include <iostream>
#include <cstring>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <string>#define PORT 8888int main()
{int server_fd, new_socket;struct sockaddr_in address;int addrlen = sizeof(address);char buffer[1024] = {0};// 创建socket文件描述符if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0){perror("socket failed");exit(EXIT_FAILURE);}address.sin_family = AF_INET;address.sin_addr.s_addr = INADDR_ANY;address.sin_port = htons(PORT);// 绑定socket到端口8888if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0){perror("bind failed");exit(EXIT_FAILURE);}// 监听端口if (listen(server_fd, 3) < 0){perror("listen");exit(EXIT_FAILURE);}std::cout << "Listening on port " << PORT << "..." << std::endl;// 接受连接if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t *)&addrlen)) < 0){perror("accept");exit(EXIT_FAILURE);}// 读取请求read(new_socket, buffer, 1024);std::cout << buffer << std::endl;// 关闭socketclose(new_socket);close(server_fd);return 0;
}

通过浏览器发送请求,结果如下: 

 请求行中 url 表示的是 web 根目录下的资源路径

  • 在请求报文的请求行中的 url 表示的是想要访问的资源的所在路径。
  • 而 url 当中的 / 不是云服务器上的根目录,而是 web 根目录
  • 这个 web 根目录可以指定为你机器上的任何一个目录,不一定就非得是 Linux 的根目录。
  • http 会设置一个前缀路径表示 web 根目录,当接收到请求时,会将这个前缀路径和 url 所表示的资源路径拼接起来。这样就可以任意访问各种路径了
  • 在进行网页请求时,如果不指明请求的资源的所在路径,默认访问的是目标网站的首页,即 web 根目录下的 index.html 文件。
  • 在进行网页请求时,如果用户指明了请求的资源所在路径,就会直接到 web 根目录下访问指定资源。

         3 . HTTP 协议的响应格式

  • 状态行:HTTP 版本 + 状态码 + 状态码描述。
  • 响应报头:响应的属性,这些属性都以 key: value 的形式按行陈列。
  • 空行:遇到空行就表示响应报头结束。
  • 响应正文:这里面存着请求的资源,一般为 html、图片、音频等内容。如果响应正文存在,则在响应报头中添加一个 content-length 属性来标识响应正文的长度。

将 HTTP 响应报文的报头和有效载荷分离

  • 对于一个 HTTP 响应报文来说,报头 = 状态行 + 响应报头;有效载荷 = 响应正文。
  • 分离方式与 HTTP 请求相同,客户端按行读取获取的响应报头,如果读取到空行则说名报头读取完毕。
  • 从代码层面上看,连续读取到两个 \n 就表示报头读取完毕。

         4 . HTTP响应代码

  • 为了更好地看到响应的效果,这里再上面的代码的基础上增加一点响应的部分,其中包含两个字段:Content-Type(正文格式,数据类型)Content-Length(正文长度) 两个字段

这里我们正文返回一个html格式的表单,具体如下:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>注册页面</title>
</head><body><!-- 表单域 form 表单域action url 地址 method 提交方式 name 表单名称--><form method = "POST" name="注册表" action="mysql_cgi"><!-- input type 属性值 --><!-- text 正常显示 password  -->用户名:<input type="text" name = "username"> <br/>密码:<input type="password" name = "password"> <br/><input type=submit value="注册"> </form></body>
</html>
  • 这里使用sendfile这个接口来发送该文本,该接口可以直接将一个文件的内容拷贝给另一个文件,且在内核中完成该操作,效率极高,

介绍:

  • sendfile 是一个在 Linux 内核中提供的系统调用,用于高效地将文件内容发送到套接字
  • 这个系统调用特别适用于需要将文件内容传输到网络上的场景,比如Web服务器传输静态文件时。
  • sendfile 的优势在于它可以直接在内核空间将数据从一个文件描述符传输到另一个文件描述符,避免了数据在内核空间和用户空间之间的复制,从而提高了数据传输的效率。

函数原型:

#include <sys/sendfile.h>ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);
  • out_fd:输出文件描述符,即套接字。
  • in_fd:输入文件描述符,即要发送的文件。
  • offset:一个指向 off_t 类型的指针,用于指定从文件的哪个位置开始发送数据。如果传递 NULL,则从当前文件偏移量开始发送。
  • count:要发送的数据量。

返回值

  • 成功时,返回实际发送的字节数。
  • 失败时,返回 -1 并设置 errno 以指示错误。
  • sendfile这个接口中,需要填充需要发送多少字节,这里我们发送整个文件,所以这里为了能够获取一个文件大小,这里再介绍一个接口stat。

介绍如下:

函数原型

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>int stat(const char *path, struct stat *buf);
  • path:指向文件路径的指针。
  • buf:指向 stat 结构体的指针,该结构体用于存储文件的状态信息。

stat 结构体

stat 结构体包含了文件的各种属性,其定义如下:

struct stat {dev_t     st_dev;     /* ID of device containing file */ino_t     st_ino;     /* inode number */mode_t    st_mode;    /* protection */nlink_t   st_nlink;   /* number of hard links */uid_t     st_uid;     /* user ID of owner */gid_t     st_gid;     /* group ID of owner */off_t     st_size;    /* total size, in bytes */blksize_t st_blksize; /* blocksize for filesystem I/O */blkcnt_t  st_blocks;  /* number of 512B blocks allocated */time_t    st_atime;   /* time of last access */time_t    st_mtime;   /* time of last modification */time_t    st_ctime;   /* time of last status change */
};

响应代码:

#include <iostream>
#include <cstring>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <string>
#include <fcntl.h>#include <sys/stat.h>#include <sys/sendfile.h>#define PORT 8888int main()
{int server_fd, new_socket;struct sockaddr_in address;int addrlen = sizeof(address);char buffer[1024] = {0};// 创建socket文件描述符if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0){perror("socket failed");exit(EXIT_FAILURE);}address.sin_family = AF_INET;address.sin_addr.s_addr = INADDR_ANY;address.sin_port = htons(PORT);// 绑定socket到端口8888if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0){perror("bind failed");exit(EXIT_FAILURE);}// 监听端口if (listen(server_fd, 3) < 0){perror("listen");exit(EXIT_FAILURE);}std::cout << "Listening on port " << PORT << "..." << std::endl;// 接受连接if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t *)&addrlen)) < 0){perror("accept");exit(EXIT_FAILURE);}// 读取请求read(new_socket, buffer, 1024);std::cout << "Client request: " << buffer << std::endl;// 响应int fd = open("index1.html", O_RDONLY);struct stat st;stat("./index1.html", &st);std::string status_line = "HTTP/1.1 200 OK\n";// 2.响应报头std::string response_header = "Content-Length: " + std::to_string(st.st_size) + "\n";response_header += "Content-Type: text/html\n";//  3.空行std::string blank = "\n";// 4.正文send(new_socket, status_line.c_str(), status_line.size(), 0);send(new_socket, response_header.c_str(), response_header.size(), 0);send(new_socket, blank.c_str(), blank.size(), 0);sendfile(new_socket, fd, nullptr, st.st_size);close(fd);// 关闭socketclose(new_socket);close(server_fd);return 0;
}

 浏览器访问结果:

用telnet做测试:

  • 另外还可以用postman之类的工具做测试。

五、HTTP常见的请求方法

列举常见的几种:

  • 说明: HTTP/1.1在HTTP/1.0基础上增加了长连接和缓存处理等内容,HTTP/1.0是基于请求与响应的,每次发送请求都需要重新建立连接获得响应后关闭连接,而HTTP/1.1是支持长连接,客户端可以通过一个连接向服务器发起多个HTTP请求,上层依次读取请求后还会保持连接。
  • 在 HTTP 的请求应用中,99% 用的都是 GET 和 POST 方法,而在这 99% 中,GET 方法又占到了 80%。
  • 网络中的行为总共就两种:上传和下载。
    • GET 可以直接获取资源,还可以上传数据,通过url进行参数的传递(例如:?a=10&b=20)

    • POST 上传数据。通过正文进行传参,报头中还会携带Content-Length字段,说明正文内容大小

         1 .GET 方法(重要)

  • 用途:向服务器发送 GET 请求,用于从服务器中获取数据 (下载)
    • GET 请求方法通过 URL 传参。客户端向服务端获取请求行中 URL 所指定的资源。
  • 栗子:GET /index.html HTTP/1.1,获取根目录下 index.html 文件的内容。
  • 特性:指定要访问的资源会在经过服务器端的解析后再返回响应内容。

         2 .POST 方法(重要)

  • 用途:向服务器发送 POST 请求,用于往服务器中传输数据 (上传)
    • POST 请求方法通过正文传参。将请求正文中的数据传输给服务器,通常用于提交表单数据。
  • 示例:POST /submit.cgi HTTP/1.1,将 submit.cgi 中的数据发送给服务器。
  • 特性:可以发送大量的数据给服务器,并且数据包含在请求正文中。

         3 . PUT 方法 (少用)

  • 用途:向服务器传输文件,将请求报文中主体中的文件保存到请求行的 URL 所指定的位置。
    • 但是向服务器随意上传文件的行为是被 HTTP 禁止的。
  • 示例:PUT /example.html HTTP/1.1,向服务器上传 example.html 文件。
  • 特性:不太常用,但在如 RESTful API 等情况下,用于更新资源。

         4 . HEAD 方法

  • 用途:GET 方法类似,但不返回报文主体部分,仅返回响应头。
  • 示例:HEAD /index.html HTTP/1.1
  • 特性:用于确认 URL 的有效性及资源更新的日期时间等。

         5 .DELETE 方法 (少用)

  • 用途:删除服务器上的文件,和 PUT 方法的功能相反,将请求行中的 URL 所指定的文件删除。
    • 但是,随意删除服务器上的文件的行为是被 HTTP 禁止的。
  • 示例:DELETE /example.html HTTP/1.1,删除服务器上的 example.html 文件。
  • 特性:删除请求行中的 URL 所指定的资源。

         6 .OPTIONS 方法

  • 用途:查询针对请求行中的 URL 所指定的资源支持的方法。
  • 示例:OPTIONS * HTTP/1.1
  • 特性:返回被允许的方法,如 GET、POST 等。

六、HTTP 的状态码

         1 .状态码的分类

  • 根据开头的数字将 HTTP 的状态码划分成 5 大类,HTTP 的状态码分类如下:

         2 .HTTP 常见状态码

  • 下面是最常见的状态码, 比如 200(OK), 404(Not Found), 403(Forbidden), 302(Redirect, 重定), 504(Bad Gateway)

         3 . Redirection 重定向状态码

  • 重定向是通过各种方法将网络请求重新定个方向转到其他位置,此时的这个服务器提供的服务相当于是引路。
    • 例:手机上APP的 摇一摇广告,刚打开软件一不小心摇了一下手机就给我重定向到淘宝。
  • 引路:客户端向 A 服务器发送 http 请求后,A 服务器返回给客户端的响应报文中,响应正文不会携带任何内容。而是会在响应报文中添加一个 Location 报头,告知客户端应该去访问指定的网站,此时客户端就会向指定网站的服务器 B 发送 http 请求报文,由服务器 B 为客户端提供服务。

重定向分类

HTTP 状态码 301(永久重定向)

  • 当服务器返回 HTTP 301 状态码时,表示请求的资源已经被永久移动到新的位置
  • 在这种情况下,服务器会在响应中添加一个 Location 头部,用于指定资源的新位置。这个 Location 头部包含了新的 URL 地址,浏览器会自动重定向到该地址。
    • 例如,在 HTTP 响应中,可能会看到类似于以下的头部信息:
    • HTTP/1.1 301 Moved Permanently\r\n
      Location: https://www.new-url.com\r\n

HTTP 状态码 302(临时重定向)

  • 当服务器返回 HTTP 302 状态码时,表示请求的资源临时被移动到新的位置
  • 同样地,服务器也会在响应中添加一个 Location 头部来指定资源的新位置。浏览器会暂时使用新的 URL 进行后续的请求,但不会缓存这个重定向。
    • 例如,在 HTTP 响应中,可能会看到类似于以下的头部信息:
    • HTTP/1.1 302 Found\r\n
      Location: https://www.new-url.com\r\n
总结
  • 无论是 HTTP 301 还是 HTTP 302 重定向,都需要依赖 Location 选项来指定资 源的新位置。这个 Location 选项是一个标准的 HTTP 响应头部,用于告诉浏览器应该 将请求重定向到哪个新的 URL 地址。

七、HTTP 的常见报头

         1 .Host 报头

  • Host 报头中存储着的是客户端真正想要访问的服务所在的 IP 地址和端口号
    • 当使用浏览器访问某个服务器时,浏览器发送的 HTTP 请求 Host 中填的就是该服务器的 IP 和端口号。
  • 由于有些服务器实际提供的是代理服务 (代替客户端向其他服务器发起请求),要访问的文件资源可能并不在当前服务器上。
    • 所以 Host 中存着的才是真正的提供服务的服务端。
  • 代理服务器要执行代理功能,首先得知道客户端要访问得资源在哪里,然后再将响应报文返回给客户端。
    • 例:如果启动了 fiddler 这个软件,浏览器发起的 http 请求就会被这个软件抓包,该软件执行的就是代理服务。
    • 该软件会代替客户端将请求报文发送给 Host 所指定的服务器,服务器就认为是该软件给它发送的请求,于是会将响应报文返回给该软件,最后该软件将响应报文发送给客户端。
    • 这也就是所谓的科学上网

         2 .User-Agent 报头

  • User-Agent 报头中存储着发送请求的客户端所对应的操作系统和浏览器的版本信息。

         3 . Referer 报头

  • Referer 记录着当前是从哪一个页面跳转过来的,方便回退到上一个页面。

         4 . Cookie 报头

  • 用于在客户端中存储少量信息,通常用于实现会话 (Session) 功能
  • HTTP 是一种无状态,无连接的协议,并不会保存客户端的信息。但在实际场景中,大部分网站都会记住你的登录信息,这就是通过 Cookie 实现的。

查看网站的Cookie

  • Cookie 用于在客户端中存储少量的信息,由于 HTTP 是一种无状态的协议 (服务器不会保存客户端的信息),如果没有 Cookie,每次页面请求时都需要重新认证用户信息。
    • 例:看 VIP 视频时,每个视频都是一个新的 HTTP 请求,如果每一集都要客户端进行 VIP 认证,这样就很麻烦。
  • HTTP 中有一个报头是 Set-Cookie,可以用来给浏览器设置 Cookie 值。
  • 当第一次登录某个网站时,需要进行用户认证。此时如果服务器在经过数据对比之后判断为合法用户,就会进行 Set-Cookie 的设置,填充用户登录信息。
  • 当认证通过并在给返回客户端的http中设置了 Set-Cookie 报头后,服务器返回给浏览器的 HTTP 响应报文就会携带上 Cookie 报头及其对应的值。
  • 客户端在收到响应报文之后,会提取出 Set-Cookie 报头中的值,并将其保存在浏览器的 Cookie 文件中,此时就将认证信息保存在本地客户端的 Cookie 文件了。
  • 往后 HTTP 发送的任何信息,都会携带上 Cookie 文件中的内容,不需要用户自己进行认证。
    对应网站的各种 Cookie 数据。
  • 看到的这些 Cookie 数据都是由对应的服务器方写的,将某些包含登陆时所设置信息的 Cookie 数据删除的话就可能会导致需要重新进行登录认证。
  • 一般Cookie也会有时间限制,超过一定时间该Cookie就会失效,需要再次认证添加新的Cookie

         5 .connection 报头

  • HTTP 中的 Connection 字段是 HTTP 报文头的一部分,它主要用于控制和管理客户端与服务器之间的连接状态
核心作用
  • 管理持久连接Connection 字段还用于管理持久连接(也称为长连接)。持久连接允许客户端和服务器在请求/响应完成后不立即关闭 TCP 连接,以便在同一个连接上发送多个请求和接收多个响应。
持久连接(长连接)
  • HTTP/1.1:在 HTTP/1.1 协议中,默认使用持久连接。当客户端和服务器都不明确指定关闭连接时,连接将保持打开状态,以便后续的请求和响应可以复用同一个连
  • HTTP/1.0:在 HTTP/1.0 协议中,默认连接是非持久的。如果希望在 HTTP/1.0上实现持久连接,需要在请求头中显式设置 Connection: keep-alive
语法格式
  • Connection: keep-alive:表示希望保持连接以复用 TCP 连接。
  • Connection: close:表示请求/响应完成后,应该关闭 TCP 连接。

八、HTTP 历史及版本核心技术与时代背景

  • HTTPHypertext Transfer Protocol,超文本传输协议)作为互联网中浏览器和服务器间通信的基石,经历了从简单到复杂、从单一到多样的发展过程。以下将按照时间顺序,介绍 HTTP 的主要版本、核心技术及其对应的时代背景。

         1 .HTTP/0.9

核心技术:
  • 仅支持 GET 请求方法
  • 仅支持纯文本传输,主要是 HTML 格式
  • 无请求和响应头信息。
时代背景
  • 1991 年,HTTP/0.9 版本作为 HTTP 协议的最初版本,用于传输基本的超文本
  • HTML 内容。
  • 当时的互联网还处于起步阶段,网页内容相对简单,主要以文本为主。

         2 .HTTP/1.0

核心技术
  • 引入 POST HEAD 请求方法。
  • 请求和响应头信息,支持多种数据格式(MIME)。
  • 支持缓存(cache)。
  • 状态码(status code)、多字符集支持等。
时代背景
  • 1996 年,随着互联网的快速发展,网页内容逐渐丰富,HTTP/1.0 版本应运而生。
  • 为了满足日益增长的网络应用需求,HTTP/1.0 增加了更多的功能和灵活性。
  • 然而,HTTP/1.0 的工作方式是每次 TCP 连接只能发送一个请求,性能上存在一定局限

         3 .HTTP/1.1

核心技术
  • 引入持久连接(persistent connection),支持管道化(pipelining)。
  • 允许在单个 TCP 连接上进行多个请求和响应,提高了性能。
  • 引入分块传输编码(chunked transfer encoding)。
  • 支持 Host 头,允许在一个 IP 地址上部署多个 Web 站点。
时代背景
  • 1999 年,随着网页加载的外部资源越来越多,HTTP/1.0 的性能问题愈发突出。
  • HTTP/1.1 通过引入持久连接和管道化等技术,有效提高了数据传输效率。
  • 同时,互联网应用开始呈现出多元化、复杂化的趋势,HTTP/1.1 的出现满足了这些需求。

         4 . HTTP/2.0

核心技术
  • 多路复用(multiplexing),一个 TCP 连接允许多个 HTTP 请求。
  • 二进制帧格式(binary framing),优化数据传输。
  • 头部压缩(header compression),减少传输开销。
  • 服务器推送(server push),提前发送资源到客户端。
时代背景
  • 2015 年,随着移动互联网的兴起和云计算技术的发展,网络应用对性能的要求越来越高。
  • HTTP/2.0 通过多路复用、二进制帧格式等技术,显著提高了数据传输效率和网络性能。
  • 同时,HTTP/2.0 还支持加密传输(HTTPS),提高了数据传输的安全性。

         5 .HTTP/3.0

核心技术
  • 使用 QUIC 协议替代 TCP 协议,基于 UDP 构建的多路复用传输协议。
  • 减少了 TCP 三次握手及 TLS 握手时间,提高了连接建立速度。
  • 解决了 TCP 中的线头阻塞问题,提高了数据传输效率。

时代背景

  • 2022 年,随着 5G、物联网等技术的快速发展,网络应用对实时性、可靠性的要求越来越高。
  • HTTP/3.0 通过使用 QUIC 协议,提高了连接建立速度和数据传输效率,满足了这些需求。
  • 同时,HTTP/3.0 还支持加密传输(HTTPS),保证了数据传输的安全性。

相关文章:

【Linux】应用层协议—HTTP

一、HTTP协议介绍 请求-响应模型&#xff1a;HTTP (Hyper Text Transfer Protocol) 协议是基于请求和响应的。客户端&#xff08;如Web浏览器&#xff09;发送一个HTTP请求到服务器&#xff0c;服务器处理请求后返回一个HTTP响应。 无状态&#xff0c;无连接协议&#xff1a;H…...

使用Vue3+Echarts实现加载中国地图,点击省份地图下钻(完整教程)

一. 前言 在众多 ECharts 图表类型中&#xff0c;开发者始终绕不开的有各种各样的地图开发&#xff0c;关于地图开发&#xff0c;可能比其他图表相对繁琐一些&#xff0c;其实说简单也简单&#xff0c;说复杂也复杂&#xff0c;其中不乏有层级地图、3D 地图等&#xff0c;感觉…...

双目相机的标定,视差图,深度图,点云生成思路与实现。

该文档记录从双目相机标定到点云生成的所有过程&#xff0c;同时会附上代码。 代码直接能跑。https://github.com/stu-yzZ/stereoCamera 目录 大致思路如下&#xff1a; 一、相机标定 1、相机参数介绍 2、单目相机标定 3、双目相机标定 二、图片畸变矫正 三、极线矫正…...

解决 minio上传文件Service: S3, Status Code: 403

错误信息 [software.amazon.awssdk.services.s3.model.S3Exception: (Service: S3, Status Code: 403, Request ID: 180E9BC04F11312E, Extended Request ID: 81aefed089495c5faf6270c59bea93c9783926f74ef647fe6b17908f0976b557)]分析过程 4XX一般是客户端错误。403表示禁止…...

SpringBoot实战——个人博客项目

目录 一、项目简介 ?二、项目整体架构 数据库模块 后端模块 前端模块 ?三、项目具体展示 ?四、项目的具体实现 1、一些准备工作 ??数据库、数据表的创建 ??设置数据库和MyBatis的配置 ??将前端项目引入到当前项目中 2、登录注册模块 ??实体类的创建 ?…...

OpenCV-平滑图像

二维卷积(图像滤波) 与一维信号一样&#xff0c;图像也可以通过各种低通滤波器&#xff08;LPF&#xff09;、高通滤波器&#xff08;HPF&#xff09;等进行过滤。LPF 有助于消除噪音、模糊图像等。HPF 滤波器有助于在图像中找到边缘。 opencv 提供了函数 **cv.filter2D()**&…...

nodejs官方文档学习-笔记-1

一、异步工作 process.nextTick()&#xff1a; 回调会在当前操作完成后立即执行&#xff0c;但在事件循环进入下一个阶段之前。它是最先执行的。 Promise.then()&#xff1a; 回调会在 microtask 队列中执行&#xff0c;通常是在当前操作完成后&#xff0c;但在事件循环进入…...

YOLOv7

YOLOv7 是 YOLO 系列的一个重要版本&#xff0c;由 Chien-Yao Wang 和 Alexey Bochkovskiy 等研究人员和开发者提出&#xff0c;继续改进了 YOLOv4 和 YOLOv5 的设计&#xff0c;主要在模型性能、训练效率以及推理速度上进行优化。YOLOv7 进一步优化了 YOLO 系列在速度和精度之…...

汉语唤醒词的模糊判断(Python)

汉语唤醒词的模糊判断【Python】 说明安装库代码Demo其他 说明 这是一个简单的汉语模糊唤醒词的判断器&#xff0c;汉语发音中前后舌以及声母韵母的区别&#xff0c;如果进行精准判断&#xff0c;很容易误判。需要一个模糊判断的逻辑! 安装库 pip install pypinyin代码Demo …...

C语言实例_26之根据输入计算星期几

1. 问题 请输入星期几的第一个字母来判断一下是星期几&#xff0c;如果第一个字母一样&#xff0c;则继续判断第二个字母。 2. 实现思路 思路一&#xff1a;嵌套if-else语句实现 首先接收用户输入的第一个字母&#xff0c;使用if-else语句进行判断。如果输入的是M&#xff0…...

包管理器npm,cnpm,yarn和pnpm

npm (Node Package Manager) 核心技术与工作原理 依赖解析&#xff1a; 广度优先搜索&#xff08;BFS&#xff09;&#xff1a;npm 使用 BFS 算法来解析依赖树&#xff0c;尽量扁平化 node_modules 目录以减少重复的依赖项。冲突处理&#xff1a;如果两个包需要同一个依赖的不…...

docker-compose部署skywalking 8.1.0

一、下载镜像 #注意 skywalking-oap-server和skywalking java agent版本强关联&#xff0c;版本需要保持一致性 docker pull elasticsearch:7.9.0 docker pull apache/skywalking-oap-server:8.1.0-es7 docker pull apache/skywalking-ui:8.1.0二、部署文件docker-compose.yam…...

Android -- [SelfView] 自定义多行歌词滚动显示器

Android – [SelfView] 自定义多行歌词滚动显示器 流畅、丝滑的滚动歌词控件* 1. 背景透明&#xff1b;* 2. 外部可控制进度变化&#xff1b;* 3. 支持屏幕拖动调节进度&#xff08;回调给外部&#xff09;&#xff1b;效果 歌词文件&#xff08;.lrc&#xff09; 一. 使用…...

记事本建java及java命名规范

1.桌面开发&#xff1a;c# 2. 记事本建java&#xff1a; 以class的名称(类名)为名&#xff0c;名称.java 编译jdk&#xff1a;javac 名称.java 调动运行jre : java 名称 查看名称.java里面的内容&#xff1a;cat 名称.java java 的命名规范 大驼峰&#xff08;每个单词首…...

Elasticsearch scroll 之滚动查询

Elasticsearch scroll 之滚动查询 Elasticsearch 的 Scroll API 是一种用于处理大规模数据集的机制&#xff0c;特别是在需要从索引中检索大量数据时。通常情况下&#xff0c;Elasticsearch 的搜索请求会有一个结果集大小的限制 (fromsize 的检索数量默认是 10,000 条记录)&am…...

cartographer建图与定位应用

文章目录 前言一、安装cartographer1.安装环境2.源码编译2.1 下载2.2 编译 二、gazebo仿真2d建图0.准备仿真环境1.编写lua文件2.编写启动文件3.建图保存 三、cartographer定位 move_base导航3.1 编写启动文件3.2 启动launch 总结 前言 本文介绍cartographer在ubuntu18.04下的…...

CEEMDAN-CPO-VMD二次分解(CEEMDAN+冠豪猪优化算法CPO优化VMD)

CEEMDAN-CPO-VMD二次分解&#xff08;CEEMDAN冠豪猪优化算法CPO优化VMD&#xff09; 目录 CEEMDAN-CPO-VMD二次分解&#xff08;CEEMDAN冠豪猪优化算法CPO优化VMD&#xff09;效果一览基本介绍程序设计参考资料 效果一览 基本介绍 首先运用CEEMDAN对数据进行一次分解&#xff…...

【Golang】Go语言编程思想(二):函数式编程

函数式编程 函数与闭包 支持函数式编程的语言当中&#xff0c;函数是一等公民&#xff0c;参数、变量、返回值都可以是函数。 以 adder 为例&#xff0c;下例实现了一个函数式编程&#xff1a; package mainimport "fmt"func adder() func(int) int {sum : 0retu…...

ros项目dual_arm_pick-place(moveit和gazebo联合仿真)(一)

目录 前言正文创建功能包具体代码运行 总结 前言 dual_arm_pick-place项目中&#xff0c;实现了两套的moveit和gazebo联合仿真。 启动文件分别是bringup_moveit.launch和arm_bringup_moveit.launch。 在这个项目中&#xff0c;我将代码重新创建了一个包&#xff0c;co_simula…...

点线面|点到两点直线距离求解

在点云库&#xff08;PCL&#xff09;中&#xff0c;计算点到直线的距离可以借助于向量运算。以下是这种计算方法的步骤以及相应的实现代码。 概念 要计算点 AA 到通过点 BB 和 CC 定义的直线的距离&#xff0c;可以使用以下步骤&#xff1a; 定义两个向量&#xff1a; 向量 …...

等保2.0三级测评华为华三交换机路由器

在使用本博客提供的学习笔记及相关内容时,请注意以下免责声明: 信息准确性:本博客的内容是基于作者的个人理解和经验,尽力确保信息的准确性和时效性,但不保证所有信息都完全正确或最新。 非专业建议:博客中的内容仅供参考,不能替代专业人士的意见和建议。在做出任何重要…...

鸿蒙分享(二):引入zrouter路由跳转+封装

码仓库&#xff1a;https://gitee.com/linguanzhong/share_harmonyos 鸿蒙api:12 鸿蒙第三方库地址&#xff1a;OpenHarmony三方库中心仓 zrouter地址&#xff1a;OpenHarmony三方库中心仓 1.引入zrouter 1.打开终端界面&#xff1a;输入 ohpm install hzw/zrouter 2.在项目…...

欧拉角和旋转矩阵之间的转换

在实际编程实践中&#xff0c;特别是使用C的Eigen库时&#xff0c;需要掌握多种空间旋转表示之间的转换。本文将深入探讨欧拉角与旋转矩阵之间的相互转换&#xff0c;这是使用库时常见的操作。 首先&#xff0c;让我们了解欧拉角。它是指通过围绕三个基本坐标轴旋转来表示三维对…...

Typora的激活

Typora的安装、激活 图文教程 | 2024年最新Typora激活使用教程合集 Typora 激活指南&#xff08;2024年最新版&#xff09; 图文教程 | 2024Typora最新版免费激活使用教程&#xff08;新旧版可用&#xff09;...

排查bug的通用思路

⭐️前言⭐️ APP点击某个按钮没有反应/PC端执行某个操作后&#xff0c;响应较慢&#xff0c;通用的问题排查方法: 从多个角度来排查问题 &#x1f349;欢迎点赞 &#x1f44d; 收藏 ⭐留言评论 &#x1f349;博主将持续更新学习记录收获&#xff0c;友友们有任何问题可以在评…...

探秘CSS3 3D转换:打造立体网页动画与视觉效果的魔法

在现代网页设计中&#xff0c;CSS3 3D转换&#xff08;3D Transforms&#xff09;已经成为一种强大的工具&#xff0c;用于创建各种动态效果和视觉吸引力。本文将详细介绍CSS3 3D转换的基本概念、常见属性及其应用示例&#xff0c;帮助您掌握这一技术&#xff0c;提升网页设计的…...

Pycharm 安装两种不同版本的解释器

背景 Pycharm使用的解释器是python3.11&#xff0c;python3.9.x之后不支持win7&#xff1b;有同事需要在win7上使用python制作的exe&#xff0c;而了“win7环境下运行python打包exe提示找不到api-ms-win-core-path-l1-1-0.dll”。 过程 查找了一些资料&#xff0c;发现直接将…...

小红薯x-s算法分析最新12-06(x-s 56)(上)

目标-小红薯达人作品&#xff1a;aHR0cHM6Ly93d3cueGlhb2hvbmdzaHUuY29tLw 1、确定目标 打上xhr断点 发现是异步请求&#xff0c;同时各个参数已经生成结束了 2、进入第二个异步函数 打上断点并继续运行 发现在e这个位置也生成了&#xff0c;那么再继续往上找异步参数进行断…...

视频融合×室内定位×数字孪生

随着物联网技术的迅猛发展&#xff0c;室内定位与视频融合技术在各行各业中得到了广泛应用。不仅能够提供精确的位置信息&#xff0c;还能通过实时视频监控实现全方位数据的可视化。 与此同时&#xff0c;数字孪生等技术的兴起为智慧城市、智慧工厂等应用提供了强大支持&#…...

JMS和消息中间件:Kafka/RocketMQ

文章目录 消息传递模型使用JMS还是KafkaKafka与RocketMQ的优缺点Kafka与RocketMQ的使用场景Kafka与RocketMQ的选型指南 TPM 项目中&#xff0c; iflow之间使用了JMS&#xff0c;后端项目与数据库通信使用Kafka MQ和JMS的区别&#xff1a; JMS是 java 用来处理消息的一个API规范…...

FreeRTOS之ARM CR5栈结构操作示意图

FreeRTOS之ARM CR5栈结构操作示意图 1 FreeRTOS源码下载地址2 ARM CR5栈结构操作宏和接口2.1 portSAVE_CONTEXT宏2.1.1 portSAVE_CONTEXT源码2.1.2 portSAVE_CONTEXT宏操作栈结构变化示意图 2.2 portRESTORE_CONTEXT宏2.2.1 portRESTORE_CONTEXT源码2.2.2 portRESTORE_CONTEXT宏…...

【技巧】Mac上如何显示键盘和鼠标操作

在制作视频教程时&#xff0c;将键盘和鼠标的操作在屏幕上显示出来&#xff0c;会帮助观众更容易地理解。 推荐Mac上两款开源的小软件。 1. KeyCastr 这款工具从2009年至今一直在更新中。 https://github.com/keycastr/keycastr 安装的话&#xff0c;可以从Github上下载最…...

三种插入排序算法

目录 1.直接插入排序 直接插入排序的步骤示例 直接插入排序的特点 适用场景 2.折半插入排序 折半插入排序的基本原理 折半插入排序的实现过程 折半插入排序的时间复杂度 折半插入排序的特点 3.希尔排序 希尔排序的基本原理 希尔排序的步骤举例 希尔排序的时间复杂…...

力扣100题--移动零

给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 请注意 &#xff0c;必须在不复制数组的情况下原地对数组进行操作。 示例 1: 输入: nums [0,1,0,3,12] 输出: [1,3,12,0,0]示例 2: 输入: nums [0] 输出: […...

第30天:安全开发-JS 应用NodeJS 指南原型链污染Express 框架功能实现审计0

时间轴&#xff1a; 演示案例&#xff1a; 环境搭建-NodeJS-解析安装&库安装 功能实现-NodeJS-数据库&文件&执行 安全问题-NodeJS-注入&RCE&原型链 案例分析-NodeJS-CTF 题目&源码审计 开发指南-NodeJS-安全 SecGuide 项目、 环境搭建-NodeJ…...

1.使用docker 部署redis Cluster模式 集群3主3从

1.使用docker 部署redis Cluster模式 集群3主3从 1.1 先安装docker 启动docker服务&#xff0c;拉取redis镜像 3主3从我们要在docker启动6个容器docker run --name redis-node-1 --net host --privilegedtrue -v /data/redis/share/redis-node-1:/data redis:6.0.8 --cluster-…...

SAP导出表结构并保存到Excel 源码程序

SAP导出表结构并保存到Excel,方便写代码时复制粘贴 经常做接口,需要copy表结构,找到了这样一个程程,特别有用。 01. 先看结果...

李飞飞:Agent AI 多模态交互的前沿探索

发布于:2024 年 11 月 27 日 星期三 北京 #RAG #李飞飞 #Agent #多模态 #大模型 Agent AI在多模态交互方面展现出巨大潜力,通过整合各类技术,在游戏、机器人、医疗等领域广泛应用。如游戏中优化NPC行为,机器人领域实现多模态操作等。然而,其面临数据隐私、偏见、可解释性…...

算法基础学习Day2(双指针)

文章目录 1.题目2.题目解答1.快乐数题目及题目解析算法学习代码提交 2.题目2题目及题目解析算法学习代码提交 1.题目 202. 快乐数 - 力扣&#xff08;LeetCode&#xff09;11. 盛最多水的容器 - 力扣&#xff08;LeetCode&#xff09; 2.题目解答 1.快乐数 题目及题目解析 …...

信奥常考点:二叉树的构建(已知中序和 前序或后序 的情况下)

一、题目引入 这是来自CCF-GESP C七级认证 2024年9月的题目。 我们在此不解题&#xff0c;只把树画出来。 CCF-GESP 编程能力认证 C 七级 2024年9月份详细解析-CSDN博客 二、解题过程 我们可以根据先序遍历得出根节点是A&#xff0c;然后我们得到了A的左子树[B D]&#xff08;橙…...

《CS2》运行时提示“缺少steam_api_64.dll”文件该如何处理?“找不到steam_api.dll,无法继续执行代码”的修复方法

《CS2》游戏运行时文件丢失、损坏与系统报错处理指南 《CS2》上海 Major 淘汰赛这两天也在如火如荼的进行当中&#xff0c;相信有很多go学长在游戏运行时会遇到各种文件丢失、损坏以及系统报错问题&#xff0c;给玩家带来极大的困扰。今天&#xff0c;我们就来详细探讨一下《C…...

MCPTT 与BTC

MCPTT&#xff08;Mission Critical Push-to-Talk&#xff09;和B-TrunC&#xff08;宽带集群&#xff09;是两种关键通信标准&#xff0c;它们分别由不同的组织制定和推广。 MCPTT&#xff08;Mission Critical Push-to-Talk&#xff09;标准由3GPP&#xff08;第三代合作伙伴…...

aardio - 汉字笔顺处理 - json转sqlite转png

本代码需要最新版 godking.conn 库&#xff0c;请自行下载&#xff01; 如果没有安装 odbc for sqlite 驱动&#xff0c;可以使用 godking.conn.driver.sqlite3.install() 安装。 也可以在此下载自行安装&#xff1a;http://www.chengxu.online/show.asp?softid267 1、将js…...

图的遍历之DFS邻接矩阵法

本题要求实现一个函数&#xff0c;对给定的用邻接矩阵存储的无向无权图&#xff0c;以及一个顶点的编号v&#xff0c;打印以v为起点的一个深度优先搜索序列。 当搜索路径不唯一时&#xff0c;总是选取编号较小的邻接点。 本题保证输入的数据&#xff08;顶点数量、起点的编号等…...

kdenlive 一个视频一左一右拼接(抖音长屏转宽屏)

参考kdenlive 剪裁_Kdenlive中的分层合成-CSDN博客 kdenlive 一个视频一左一右拼接&#xff08;抖音长屏转宽屏&#xff09; 按照图片的操作...

深度学习-53-AI应用实战之基于labelImg和labelme的手动标注

文章目录 1 labelImg1.1 简介1.2 安装使用1.3 文件格式1.3.1 pascalVOC格式1.3.2 yolo格式1.4 验证显示2 labelme2.1 简介2.2 安装使用2.3 labelme转换为yolo3 参考附录1 labelImg 1.1 简介 labelImg(label image)是一个开源的图像标注工具,用于创建图像标注数据集。它提供了…...

白鲸优化算法原理,白鲸算法公式,白鲸算法应用(白鲸算法测试效果,白鲸算法优化BP神经网络,白鲸算法路径优化)

‌目录 白鲸算法主要原理 白鲸算法主要公式 白鲸算法应用案例 白鲸算法主要原理 白鲸优化算法(Beluga Whale Optimization Algorithm,BWO)是一种基于种群的元启发式优化算法,灵感来源于白鲸的生活行为。‌该算法通过模拟白鲸的游泳、捕食和鲸落行为来实现模型参数的优化…...

KubeEdge、ThingsBoard 和 CnosDB:智能物联网平台的完美组合

概述 在数字化时代&#xff0c;物联网&#xff08;IoT&#xff09;正在改变我们的生活和工作方式。KubeEdge、ThingsBoard 和 CnosDB 是三个领先的开源平台&#xff0c;它们在物联网领域各自发挥着重要的作用&#xff0c;并且可以无缝集成&#xff0c;为用户提供强大的解决方案…...

最简单的线性回归神经网络

数据&#xff1a; # 线性回归 import torch import numpy as np import matplotlib.pyplot as plt# 随机种子&#xff0c;确保每次运行结果一致 torch.manual_seed(42)# 生成训练数据 X torch.randn(100, 3) # 100 个样本&#xff0c;每个样本 3 个特征 true_w torch.tenso…...

[软件工程]九.可依赖系统(Dependable Systems)

9.1什么是系统的可靠性&#xff08;reliability&#xff09; 系统的可靠性反映了用户对系统的信任程度。它反映了用户对其能够按照预期运行且正常使用中不会失效的信心程度。 9.2什么是可依赖性&#xff08;dependablity&#xff09;的目的 其目的是覆盖系统的可用性&#x…...