【Linux】HTTP协议

文章目录

  • 📖 前言
  • 1. 认识URL && 引入http协议
  • 2. http协议格式
    • 2.1 宏观格式:
    • 2.2 实验演示:
  • 3. http的方法
    • 3.1 GET方法:
    • 3.2 POST方法:
    • 3.3 GET vs POST:
  • 4. HTTP的报头和状态码
  • 5. http的cookie
    • 5.1 http协议的无状态:
    • 5.2 cookie的安全问题:
  • 6. http1.1长连接

📖 前言

从本章开始,我们要自顶向下的学习网络协议,有了前面的基础,我们再学习http协议就更容易理解了。本章的目标是学习http协议,熟悉http的协议格式,方法,状态码等概念,并且对http常见的报头进行学习。目标已经确定,准备开讲啦… 👉 【网络层状结构复习】


1. 认识URL && 引入http协议

平时我们俗称的 "网址" 其实就是说的 URL。

URL是(Uniform Resource Locator)的缩写,意为统一资源定位符:

在这里插入图片描述
我们上一章节学习的 序列化与反序列化 所做的工作是在那一层呢?—— 应用层!

我们再来复盘一下之前的网络编程的过程:

  • 基本系统socket接口的使用
  • 指定协议
  • 编写业务

那么有没有已经非常成熟的场景,自定义的协议,这个协议写的不错,然后成了应用层特定协议的标准被别人直接使用呢?有的!!

比如说:http、https、smpt、ftp、DNS…

在解析完协议之后需要被反序列化,变成结构化数据。之后才形成完整的请求,最后才能交给业务被计算。

使用确定协议的时候,一般显示的时会缺省端口号:

  • 缺省的意思是在URL上,或者分享的链接上,不用带端口号。
  • 并不代表发送请求的时候是没有的,它是有的!而且是必须得有!
  • 任何一个浏览器或者手机app,收到链接点开的时候,浏览器或者app必须自动添加上端口号!
  • 只不过没有在URL中体现出来。

所以,浏览器访问指定的URL的时候,浏览器必须给我们自动添加port。

浏览器如何得知,URL匹配的port是谁呢?特定的众所周知服务,端口号必须是确定的!!

例如:httpserver->80httpsServer->443ssh->22

服务和端口是必须绑定的,用户自己写的网络服务bind端口的时候,只能绑定1024之后的端口[1024 ~ n]

域名和DNS:

  • 域名是指互联网上某个服务器的地址名称,用于标识和定位一个互联网上的资源。
  • 域名通常由多个部分组成,以点号(.)分隔,例如:baidu.com
  • 域名系统 (DNS) 可以将域名转换为IP地址以便计算机能够访问该服务器上的资源。
  • 使用域名比直接使用IP地址更方便易记,因此被广泛应用于互联网上的各种服务。

浏览器加一个服务,DNS服务自动帮我们做的域名解析。域名必须被转化成为IP访问网络服务,服务端必须具有port。网络通信的本质:socket。(ip + port)

URL编码问题:

  • urlencodeurldecode是用于对URL中的特殊字符进行编码和解码的函数。
  • urlencode函数将URL中的特殊字符转换为%后面跟着两位十六进制数的形式。
  • urldecode函数则进行相反的操作,它将编码过的URL字符串解码回原始的字符串形式。

在这里插入图片描述
发起http请求的时候,有些字段时需要编码的,注意:编码并不等于加密。一个%后面跟两个16进制数,代表的就是一个字符,汉字是三个字符代表一个汉字的,所以两个汉字是6个百分号。

信息在本地编码之后,交给服务器端,服务器再对编码进行解码。所以就需要encode和decode。编码是浏览器做的,而解码是服务端做的。

http是做什么的?

http超文本传输协议,为什么叫超文本的,因为网页是文本的,超在哪呢?超在可以传图片,视频音频。

查阅文档,看音视频都是以网页的形式呈现的,http获取网页资源的视频,音频等也都是文件。
在这里插入图片描述

  • http是向特定的服务器申请特定的“资源"的,获取到本地,进行展示或者某种使用的。
  • 如果我们客户端没有获取的时候,资源在哪里呢?
    • 就在的网路服务器(软件)所在的服务器,硬件,计算机上。
  • 服务器都是什么系统呢?
    • Linux!
  • 这些资源都是文件,都在Linux服务器上,要打开资源文件、读取、发送会给客户端的前提:
    • 软件服务器,必先找到这个文件!
  • Linux要如何找到文件呢?
    • 通过路径!

在这里插入图片描述

  • 网络视角下,Linux服务器上的所有的东西,我们都称之为资源。
  • 无论是图片视频音频还是网页,都叫做资源。
  • http就是从本地向服务端获取资源的,这就是http协议。

举个栗子:

在这里插入图片描述

抓到了百度的网页,这个网页,就是通过百度对应的服务器,通过一些客户端,可以是浏览器或者是一些工具,把它的网页拿下来了,就是文件。

为什么URL可以定位唯一的资源:

  • 索要访问的某种资源,一定是在全球特定的主机上的,以特定的服务的方式,在特定的路径下保存着的。
  • 因为ip地址定位到了全球当中唯一的主机,端口号定位了主机上唯一的服务,所以ip + port定位了互联网中唯一的服务。
  • 路径一定是在该主机上的,所以路径本身就具备唯一性。
  • 所以就能使用URL定位在全球当中的任意一个资源。

2. http协议格式

2.1 宏观格式:

在这里插入图片描述
这么多行,主体是很多http请求的报头属性,请求报头的报头属性非常多,所有的字段都是Key:空格value

http是一个基于行的一个协议:

  • 报头最后一行是一个空行,能够保证,前面的内容不会是空行,而且必须有字段。
  • 按照http协议在读取的时候,可以按行去读,直到读到空行,就能证明将报头和请求行读完了。
  • 相当于用一个空行来作为一个分隔符,让自己的报头能够全被解析出去。
  • 任何一个协议都要解决一个问题, 将自己的有效载荷和自己的报头分离的问题。

任何协议的request or response都是:报头 + 有效载荷。

  • http如何保证自己的报头和有效载荷被全部读取呢?(无论是请求还是响应)
    • 读取完整报头:按行读取,直到读取到空行!
  • 你又如何保证,你能读取到完整的正文呢?
    • 报头能读取完毕,请求或者响应属性中,一定要包含正文的长度!

当对http有了宏观结构上的认识之后,也有一些不规范的写法,http请求当中可能会少一些报头,可能会没有正文,但是都必须有请求行和空行。空行存在的最大意义就是将报头和有效载荷分离。

ip具有唯一性,端口在该服务器上也具有唯一性,那么路径就更具有唯一性了。诸多唯一性构建起来就构成了一个URL。

2.2 实验演示:

有了之前的套接字编程经验,我们直接写一个简易版的服务端(TCP套接字):

class ServerTcp
{
public:ServerTcp(uint16_t port, const std::string &ip = ""): port_(port),ip_(ip),listenSock_(-1){quit_ = false;}~ServerTcp(){if (listenSock_ >= 0)close(listenSock_);}public:void init(){// 1. 创建socketlistenSock_ = socket(PF_INET, SOCK_STREAM, 0);if (listenSock_ < 0){exit(1);}// 2. bind绑定// 2.1 填充服务器信息struct sockaddr_in local; // 用户栈memset(&local, 0, sizeof local);local.sin_family = PF_INET;local.sin_port = htons(port_);ip_.empty() ? (local.sin_addr.s_addr = INADDR_ANY) : (inet_aton(ip_.c_str(), &local.sin_addr));// 2.2 本地socket信息,写入sock_对应的内核区域if (bind(listenSock_, (const struct sockaddr *)&local, sizeof local) < 0){exit(2);}// 3. 监听socket,为何要监听呢?tcp是面向连接的!if (listen(listenSock_, 5 /*后面再说*/) < 0){exit(3);}// 运行别人来连接你了}void loop(){signal(SIGCHLD, SIG_IGN); // only Linuxwhile (!quit_){struct sockaddr_in peer;socklen_t len = sizeof(peer);int serviceSock = accept(listenSock_, (struct sockaddr *)&peer, &len);if (quit_)break;if (serviceSock < 0){// 获取链接失败cerr << "accept error ...." << endl;continue;}// 多进程版本pid_t id = fork();assert(id != -1);if (id == 0){close(listenSock_); // 建议if (fork() > 0)exit(0);// 孙子进程handlerHttpRequest(serviceSock);exit(0); // 进入僵尸}close(serviceSock);wait(nullptr);}}
private:// sockint listenSock_;// portuint16_t port_;// ipstd::string ip_;// 安全退出bool quit_;
};

不清楚的小伙伴看过来 👉 TCP套接字复习。
我们用的是多进程版本的服务器。

提前搞一些宏标识:

#define CRLF "\r\n"
#define SPACE " "
#define SPACE_LEN strlen(SPACE)
#define HOME_PAGE "index.html"
#define ROOT_PATH "wwwroot"

服务端响应:

void handlerHttpRequest(int sock)
{char buffer[1024];ssize_t s = read(sock, buffer, sizeof buffer);if (s > 0)cout << buffer;std::string path = getPath(buffer);// path = "/a/b/index.html";// recource = "./wwwroot"; // 我们的web根目录// recource += path; // 最终拼出来了--> ./wwwroot/a/b/index.html// 1. 文件在哪里? 在请求的请求行中,第二个字段就是你要访问的文件// 2. 如何读取std::string recource = ROOT_PATH;recource += path;cout << "[recoure]: " << recource << std::endl;std::string html = readFile(recource);std::size_t pos = recource.rfind(".");std::string suffix = recource.substr(pos);cout << "[suffix]: " <<suffix << endl;// 开始响应std::string response;// 两百这个状态码代表这次请求时OK的response = "HTTP/1.0 200 OK\r\n";if (suffix == ".jpg")response += "Content-Type: image/jpeg\r\n"; // Content-type标定了正文的类型是什么elseresponse += "Content-Type: text/html\r\n";response += ("Content-Length: " + std::to_string(html.size()) + "\r\n");response += "\r\n"; // 空行response += html; // 正文send(sock, response.c_str(), response.size(), 0);
}

首先我们读取收到的序列化数据,提取要获取的数据的路径,根据路径在服务器上找对应的文件,然后将文件提取出来。
随后开始响应,填写响应报头,根据文件的格式填好每个报头字段,将提取到的文件拼接到最后,然后发送给客户端。

Content-type标定了正文的类型是什么,要根据不同的格式来填Content-type。👉 常用对照表

获取路径函数:

std::string getPath(std::string http_request)
{std::size_t pos = http_request.find(CRLF);if (pos == std::string::npos)return "";// 请求行std::string request_line = http_request.substr(0, pos);// GET /a/b/c http/1.1std::size_t first = request_line.find(SPACE);if (first == std::string::npos)return "";std::size_t second = request_line.rfind(SPACE);if (second == std::string::npos)return "";std::string path = request_line.substr(first + SPACE_LEN, second - (first + SPACE_LEN));if (path.size() == 1 && path[0] == '/')path += HOME_PAGE;return path;
}

注意:

  • 在http请求中默认访问的文件路径是根目录,也称为网站的根目录或文档根目录。
  • 但是这个根目录并不是服务器的根目录,难不成将服务器所有内容返回给客户端吗,不现实!

读取文件函数:

std::string readFile(const std::string &recource)
{std::ifstream in(recource, std::ifstream::binary);// 检测文件是否成功打开了if (!in.is_open())return "404";std::string content;std::string line;while (std::getline(in, line))content += line;in.close();return content;
}

资源文件:

<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>测试</title>
</head><body><h3>hello my server!</h3><p>我终于测试完了我的代码</p><form action="/a/b/c.html" method="post">Username: <input type="text" name="user"><br>Password: <input type="password" name="passwd"><br><input type="submit" value="Submit"></form>
</body></html>

当然了,我们也不懂前端,随便写一点样例。

主函数:

#include "server.hpp"static void Usage(std::string proc)
{std::cerr << "Usage:\n\t" << proc << " port" << std::endl;std::cerr << "example:\n\t" << proc << " 8080\n"<< std::endl;
}// ./ServerTcp local_port local_ip
int main(int argc, char *argv[])
{if (argc != 2){Usage(argv[0]);exit(0);}uint16_t port = atoi(argv[1]);ServerTcp svr(port);svr.init();svr.loop();return 0;
}

用浏览器获取响应:

在这里插入图片描述
用tenlnet获取响应:

在这里插入图片描述
telnet是个命令,可以远程的以协议的方式,去登录某种服务:
在这里插入图片描述
一般我们浏览器中请求的服务,是一定有人曾经写过这样的服务,部署在Linux上,然后才可以请求。


3. http的方法

方法描述
GET请求指定的资源。返回响应主体
POST向指定资源提交数据进行处理请求。通常用于提交表单或上传文件
PUT从客户端向服务器传送的数据取代指定的文档的内容
DELETE请求服务器删除指定的资源
HEAD获取对应的HTTP报头信息,但不返回响应主体
OPTIONS返回服务器支持的HTTP方法列表
PATCH对资源进行部分修改

http的请求方法除了GET和POST还有其他方法,但是用的特别少,而且在大部分的服务器当中,基本上很多的方法被注释掉了,被禁掉了。

input标签,会在网页当中给我们构建一个输入框。

URL可以在?后面带参数,参数是KV的,K对应的就是表单当中的name,V就是往表单当中输入的东西。

在这里插入图片描述
我们的网络行为无非有两种:

  1. 我想把远端的资源拿到你的本地:GET /index.html http/1.1
  2. 我们想把本地属性字段,提交到远端:GET or POST

3.1 GET方法:

在HTTP中GET会以明文方式将我们对应的参数信息,拼接到URL中,以这样的方式完成了提参的过程。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

HTTP GET方法通常不包含请求正文。HTTP GET方法用于从服务器请求资源,通常通过在URL中指定参数来传递请求参数,而不是在请求正文中传递参数。GET方法将请求参数附加到URL的末尾,形成查询字符串,并将其发送到服务器。

3.2 POST方法:

POST方法提交参数,会将参数以明文的方式,拼接到http的正文中来进行提交!

在这里插入图片描述
在这里插入图片描述
POST方法,请求正文,一般携带的是http请求所带的参数。这个参数类似于C语言C++的字符串。
在浏览器中提交表单的时候,表单的内容以KV的方式拼接到正文了。

3.3 GET vs POST:

小结:

  1. GET通过URL传参
  2. POST通过正文传参
  3. GET方法传参不私密
  4. POST方法因为通过正文传参,所以相对比较私密一些
  5. GET通过URL传参,POST通过正文传参,所以一般一些比较大的内容都是通过POST方式传参的

http传输数据能有功能上的满足,但是数据却在网络当中裸奔。所以,这个数据无论如何都是不安全的。

如何选择:

  • URL没有类型字段,而是在请求和响应报文的头部中使用Content-Type字段来指定数据类型。
  • 所以就决定了,正文部分可以传递更丰富的字段类型。
  • URL要是传一些二进制内容,而且量太大了,挺不合适的。
  • 所以如果我们平时传一些文件,对私密性有要求,并且体积比较大的,我们一般就用POST。

比如网页端上传一些简历,上传一些视频,或者是上传百度云盘的资料,我们都用的是POST来传,因为POST有详细的字段类型说明。


4. HTTP的报头和状态码

http常见的Header:

Header描述
Content-Type数据类型,指示服务器返回的正文部分的数据类型
Content-Length有效载荷的长度
Host客户端告知服务器所请求的资源在哪个主机的哪个端口
User-Agent声明用户的操作系统和浏览器版本信息
Referer当前页面是从哪个页面跳转过来的
Location搭配3xx状态码使用,告诉客户端接下来要去哪里访问
Cookie在客户端存储少量信息,通常用于实现会话功能

Linux网页的跳转本质是Linux目录的跳转,referer代表上一个目录是什么。

http这样的协议几乎是基于纯文本的,而且可展性还非常强,如果未来http想要新功能,新属性,直接在请求和响应报头里添加KV字符串行就可以。

状态码:

状态码范围类别描述
1XX信息性状态码服务器已接受请求,需要客户端继续操作
2XX成功状态码请求已成功处理
3XX重定向状态码需要完成进一步的操作以完成请求
4XX客户端错误状态码请求包含语法错误或无法完成请求
5XX服务器错误状态码服务器在处理请求时发生内部错误或超时等

目前被主流浏览器所接受的重定向是301和302。

301和302通常是做什么的呢?

  • 301:永久重定向
  • 302: 临时重定向

临时重定向:

  • 假设要访问某个网站,但是这个网站局部性的有内容要升级,并不想让用户访问这个服务。
  • 当有用户来访问时,我们就将其重定向到备份的服务当中,当内容升级完了,再将临时重定向去掉。
  • 客户端再来访问时,就可以访问到了。

永久重定向:

  • 老网站的用户数量非常的多但是想要用户去访问新的网站。
  • 所以将新网站推出,让别人能够访问,其次老网站不关。
  • 将所有的服务全部下线,并且只提供一个功能,在用户请求它时重定向就可以了。

在这里插入图片描述
重定向代码:

void handlerHttpRequest(int sock)
{char buffer[1024];ssize_t s = read(sock, buffer, sizeof buffer);if (s > 0)cout << buffer;std::string response = "HTTP/1.1 302 Temporarily Moved\r\n";// std::string response = "HTTP/1.1 301 Permanently Moved\r\n";// Location后面填的一定是个网址response += "Location: https://www.qq.com/\r\n"; response += "\r\n";send(sock, response.c_str(), response.size(), 0);
}

在响应时状态码填的是301或者302,代表的意思是重定向,给客户端响应,还会给一个新的网址。

因为我们是服务端将从客户端收到的报文打印出来,所以当客户端请求时,会将请求报文打印出来,然后再将带有location的报文发给客户端。
但是我们是打印不出来带有location字段的报文的,因为客户端重定向到了别的服务器了。

浏览器演示图:

在这里插入图片描述

telnet演示图:

在这里插入图片描述

通过Telnet可以获取远端服务器的响应。当你使用Telnet连接到远程服务器后,你可以输入命令并发送给服务器,然后等待服务器的响应。服务器会返回相应的结果,包括命令执行的输出、状态信息等。

小结:

  • 永久和临时的区别,它俩的应用场景是不一样的,对客户端的影响也是不一样的。
  • 也有其他的重定向例如307,因为其他重定向对应的浏览器的支持并不好,不一定被所有的浏览器所接受。
  • 但是301和302是被所有浏览器接受的。

5. http的cookie

5.1 http协议的无状态:

http协议特点之一:无状态

是什么意思呢?

—— 用户的各种资源请求行为,http本身并不做任何记录!!

HTTP的无状态(Stateless)指的是:

  • 每个HTTP请求都是独立的,服务器不会保存与之前请求相关的任何信息。
  • 每个请求都包含足够的信息以便服务器能够理解和处理该请求,而无需依赖于之前的请求。

但是用户需要会话保持!!

HTTP的Cookie(也称为HTTP Cookie、Web Cookie或浏览器Cookie)

是一种用于网站与浏览器之间进行状态管理的技术。它通过在用户浏览器中存储少量数据,并在以后的请求中发送给同一网站,实现对用户状态的追踪和识别。

  • 当用户第一次访问一个网站时,网站服务器可以通过HTTP响应报头中的Set-Cookie字段将一个Cookie发送给用户。
  • 浏览器会将这个Cookie存储起来,并在用户以后对同一网站发送请求时,通过HTTP请求头中的Cookie字段将这个Cookie发送回服务器。

编写响应报文:

在这里插入图片描述
获取服务器的响应:

在这里插入图片描述
第二次以后的请求会携带一个字段叫做cookie,就代表我们曾经写的内容:

在这里插入图片描述

  • 当写入一个cookie之后,在进行后续的访问时,浏览器请求,都会帮我们携带曾经写入到浏览器对应的cookie信息。
  • cookie文件内容,所以后端认证时,就不需要再输入用户名和密码了,就可以始终以登录状态,来进行访问。
  • 通过使用Cookie,服务端可以保持跟踪客户端的会话信息、用户认证状态等。同时,客户端也可以根据需要修改和删除Cookie值。

cookie就是浏览器帮我们维护的一个文件:

  • 浏览器维护的文件,存在磁盘或者内存级。
  • 只要不关闭这个浏览器,cookie文件依旧在,但是如果把浏览器结束掉,那么cookie文件就没了。
  • 不同的浏览器和不同的设备(如电脑、手机等)可能具有不同的Cookie策略和存储方式。

在浏览器中查看Cookie:

在这里插入图片描述

5.2 cookie的安全问题:

当第一次客户端请求服务端的时候,将用户账号和密码发给服务端,服务端完成匹配之后,将携带用户账号和密码的Cookie文件返回给客户端,但是这是极其不安全的!

一旦有中间人在服务端返回给客户端的时候,将返回内容截取,那么用户的账号和密码就会泄露。

现在主流的是:cookie + session

服务端在收到客户端请求时,在内部验证信息,一旦验证通过,不再给客户端返回携带用户账号和密码的Cookie文件,而是在服务端本地形成一个session文件!

  • 用户的临时私密信息,保存在自动形成的session文件中。
    • session_id是具有唯一性的,是一个用于标识和跟踪用户会话状态的唯一标识符。
  • 用户的所有信息,此时就不在客户端cookie维护了,而是在服务端将用户所有私有信息维护起来。
  • 实际上,用户的个人信息通常存储在服务器端的一个数据结构(如内存、数据库)中。
    • 服务器会根据Session ID来查找相应的会话数据,从而获取用户的个人信息。

session里包含了文件的私密信息,包括了这个用户是谁,浏览痕迹是什么,最近一次访问时间是什么时候session有没有过期等等。只要拿着session_id找到session文件,就证明用户处于登录状态,然后服务器就允许该用户去访问指定资源。

依旧存在安全问题:

  • 从此往后,客户再去访问时,都会携带自己的session_id,从而来保持这个客户处于在线状态。
  • 但是还是没有彻底解决相应问题,这样只解决了私密信息不会泄露了。
  • 因为用户名和密码在服务端,黑客只能拿到session_id,对于用户来讲,账号至少是安全的。

6. http1.1长连接

用户所看到的完整的网页内容,背后可能是无数次http清求!http底层主流采用的就是tcp协议!

长连接(Connection: keep-alive):

  • 一次http请求,获取一张给用户呈现的完整网页时,http建立一 个连接。
  • 此时服务端和客户端双方,都要进行http版本协商,所以这二者都要携带上自己http协议的版本。
  • 请求时是http1.1,响应时也是http1.1,同时还携带了一个Connection字段,叫做keep-alive
  • 双方如果都是http1.1,并且字段都携带keep-alive,意味着我们在进行底层连接协商的时候,双方都同意采用长连接方案。

http1.0当中是基于短连接的,短连接一次只处理一个http请求!Connection: closed

对于长连接的理解:

一张网页有若干个元素构成,我们在底层发起请求,这个连接暂时不断开,发起若干次http请求,同时把若干次http请求全部都发送到服务器,服务器从一个连接里读到的,不仅仅是一个请求,它可以读到很多请求,然后按照顺序,再把若干个响应全部都返回给客户端,当客户端拿到了完整的网页时,这个连接才断开。
也就是说一次获取若干个元素时,这些若干个元素用一条连接全部请求和响应,不用重复的建立TCP底层的三次握手,四次挥手。这样就能大大的提高效率。

其中双方支持长连接协商的时候,Connection如果是keep-alive,客户端发的请求里带了,服务端的响应里带了,就说明双发协商成功,我们双方都认可采用keep-alive,也叫做连接保活的策略。

因为http1.1有了keep-alive,为了区分http1.0,所以原来的Connection如果是close,就叫做只支持短连接。

如果http请求每次都采用短连接的话:

  • 最大的成本就是在底层要不断地进行三次握手和四次挥手。
  • 这就大大降低了获取的速度,所以短连接就不再符合时宜。

怎么请求的就怎么晌应(按照顺序响应):pipeline技术。

一个连接有多个请求了,如何保证服务端读取请求时,都是一个完整的请求呢?

  • 根据报文中的Content-length来读取。
  • 能保证读到的是一个完整的请求,也能保证不会读到别的请求。
  • 经过报头和有效载荷合理分离,就能做到将报文和报文之间做到完整分离。
  • 那么多个http请求能够向服务端同时发起多个请求。

http是基于tcp的,tcp协议是面向连接的,但是http是无连接的,怎么解释?(重点)

  • http协议和tcp协议是两层协议,是毫无相关的,tcp的面向连接和http无关。
  • http是无连接的,只是用了一下tcp的能力,把信道建立好,用tcp来完成http的工作,比如说发起http请求。
  • 但是http在通信时,并不会建立连接。

所以,http最核心的特点是超文本传输协议,是一个无连接,无状态的一个应用层协议,这就是http的定义。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/105884.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

估算总体标准差的极差均值估计法sigma = R/d2

总体标准差的估算值可以通过将平均极差除以合适的常数因子d2来计算。这个估算方法是用于估算总体标准差的一种常见方法&#xff0c;尤其在质量控制和过程监控中经常使用。 总体标准差的估算值 (平均极差) / d2 其中&#xff1a; "总体标准差的估算值" 表示用极差…

Floorplanning with Graph Attention

Floorplanning with Graph Attention DAC ’22 目录 Floorplanning with Graph Attention摘要1.简介2.相关工作3.问题公式化4. FLORA的方法4.1 解决方案概述4.2 C-谱聚类算法 4.3 基于GAT的模型4.4 合成训练数据集生成 摘要 布图规划一直是一个关键的物理设计任务&#xff0…

宝塔面板部署express以及MySql项目

第一次在宝塔面板上部署express和MySql项目&#xff0c;部署过程一直跑不通接口&#xff0c;特此记录一下。 在部署的时候&#xff0c;建议第一步把数据库MySql给跑通&#xff0c;中间好多原因是由于数据库的原因给引起的。 一.连接数据库 &#xff08;1&#xff09;在宝塔面…

深入promise

深入promise 我们可能知道如何使用 Promise&#xff0c;但是我们知道它们实际上是如何工作的吗&#xff1f; 为了让每个人都了解Promise&#xff0c;让我们从基础开始。如果我们知道 Promise 是什么以及如何使用它&#xff0c;我们可以跳过这一部分并直接跳到“魔法开始”的地…

RSA加密与解密原理

目录 一、什么是RSA加密 二、RSA加密原理 三、RSA加解密过程与算法代码 一、什么是RSA加密 RSA加密是一种非对称加密算法。 对称加密&#xff1a; 对称加密是一种加密方式&#xff0c;加密和解密使用同一个密钥&#xff0c;被加密的信息在传输前用预先协商好的密钥进行加密…

KUKA机器人如何强制输出或取消数字IO信号?

KUKA机器人如何强制输出或取消数字IO信号? 具体的操作方法和步骤可参考以下内容: 如下图所示,点击菜单—显示—输入/输出端,如下图所示,选择想要查看的信号,这里以数字输出端为例进行说明, 如下图所示,此时可以看到输出端信号的编号、名称和当前值,可以通过下拉滚动条…

河北专升本(C语言)

目录 一&#xff1a;C语言的构成特点 二: 数据类型 三: 常量、变量、运算符及表达式 &#xff08;一&#xff09;标识符 &#xff08;二&#xff09;常量 &#xff08;三&#xff09;变量&#xff1a;其值可以改变的量 &#xff08;四&#xff09;各种类型数据混合运算 &…

简单好用的解压缩软件:keka 中文 for mac

Keka是一款功能全面、易于使用的文件压缩和解压缩软件&#xff0c;为Mac用户提供了便捷的文件管理工具。它支持多种压缩格式&#xff0c;具有快速解压和强大的压缩功能&#xff0c;让您能够轻松地处理各种文件压缩需求。 隐私非常重要 安全共享只需设置密码并创建高度加密的文…

深度强化学习 第 2 章 蒙特卡洛

2.1随机变量 强化学习中会经常用到两个概念&#xff1a; 随机变量、 观测值。 本书用大写字母表示随机变量&#xff0c;小写字母表示观测值&#xff0c;避免造成混淆。 下面我们定义概率质量函数&#xff08;probability mass function&#xff0c;缩写 PMF&#xff09;和概率…

LINUX定时解压缩方案

需求背景 对接客户中某个上游为外包系统&#xff0c;外包系统每日推送压缩文件至指定文件夹下&#xff0c;文件格式为YYYYMMDD_RegReport.zip。由于每日采集文件&#xff0c;无法对接压缩包内文件&#xff0c;需要将推送的压缩文件每日解压为文件夹 需求分析 与客户沟通后&a…

HarmonyOS 远端状态订阅开发实例

IPC/RPC 提供对远端 Stub 对象状态的订阅机制&#xff0c; 在远端 Stub 对象消亡时&#xff0c;可触发消亡通知告诉本地 Proxy 对象。这种状态通知订阅需要调用特定接口完成&#xff0c;当不再需要订阅时也需要调用特定接口取消。使用这种订阅机制的用户&#xff0c;需要实现消…

C++初阶(1)

W...Y的主页&#x1f60a; 代码仓库分享&#x1f495; ​ &#x1f354;前言&#xff1a; 今天我们正式进入C篇章&#xff0c;作为学过C语言的同志&#xff0c;继续学习C肯定就不会进行那些与C语言相同的学习&#xff0c;因为C语言的内容在C中也可以正常使用&#xff0c;所…

通过示例详细了解ES6导入导出模块

通过示例详细了解ES6导入导出模块 似乎许多开发人员认为 ES6 模块只不过是export、import关键字。事实上&#xff0c;它更加多样化。它拥有强大的功能和鲜为人知的问题。在本文中&#xff0c;我们将使用一些示例来了解这些内容。 示例一 // index.mjs import { default } fr…

flask vue跨域问题

问题&#xff1a; 调试时候跨域访问报&#xff1a; Request header field authorization is not allowed by Access-Control-Allow-Headers in preflight response. 解决办法&#xff1a; 安装flask_cros from flask_cors import CORS CORS(app) app.after_request def a…

如何避免大语言模型绕过知识库乱答的情况?LlamaIndex 原理与应用简介

本文首发于博客 LLM 应用开发实践 随着 LangChain LLM 方案快速普及&#xff0c;知识问答类应用的开发变得容易&#xff0c;但是面对回答准确度要求较高的场景&#xff0c;则暴露出一些局限性&#xff0c;比如向量查询方式得到的内容不匹配&#xff0c;LLM 对意图识别不准。所…

【Linux】多线程

文章目录 一.Linux线程概念1.什么是线程2.二级页表3.线程的优点4.线程的缺点5.线程异常6.线程用途 二.Linux进程VS线程1.进程和线程2.进程的多个线程共享3.进程和线程的关系 三.Linux线程控制1.POSIX线程库2.线程创建3.线程等待4.线程终止5.分离线程6.线程ID及进程地址空间布局…

手机拍摄的视频噪点很多怎么办,视频怎么做降噪处理?

现如今&#xff0c;智能手机已经成为了我们生活中必不可少的存在。而随着智能手机越来越强大&#xff0c;很多人已经开始使用手机来拍摄各种类型的视频。但是由于手机的限制&#xff0c;很多人会发现自己拍摄的视频存在着很多的噪点。那么&#xff0c;我们该怎样来解决拍摄视频…

N点复序列求2个N点实序列的快速傅里叶变换

一、方法简介 通过一个点复数序列求出两个点实数序列的离散傅里叶变换&#xff0c;进一步提升快速傅里叶变换的效率。 二、方法详解 和是实数序列&#xff0c;且长度都为&#xff0c;定义复数序列&#xff1a; &#xff0c; 则序列和可表示为&#xff1a; 的离散傅…

端到端的机器学习项目(Machine Learning 研习之六)

使用真实数据 当你在研习机器学习时&#xff0c;最好是使用真实世界中的数据&#xff0c;而不是采用人工数据。巧的是&#xff0c;数以千计的数据集可供选择&#xff0c;涵盖了各种领域。 流行的开放数据存储库&#xff1a; OpenML.orgKaggle.compaperswithcode.com UC Irvin…

MAYA教程之模型的UV拆分与材质介绍

什么是UV 模型制作完成后&#xff0c;需要给模型进行贴图&#xff0c;就需要用到UV功能 UV编译器介绍 打开UI编译器 主菜单有一个 UV->UV编译器&#xff0c;可以点击打开 创建一个模型&#xff0c;可以看到模型默认的UV UV编译器功能使用 UV模式的选择 在UV编译器中…