应用层协议——http协议和https协议

目录

一、HTTP协议

1、概念

2、URL

二、HTTP协议格式

1、请求协议格式

2、响应协议格式

三、HTTP的请求方法

四、HTTP的状态码

五、HTTP常见的报头

六、HTTP和HTTPS

1、HTTPS协议

2、HTTPS的加密原理

1、基本概念

2、加密原理


通常我们程序员在网络编程的时候,一般是处于应用层的。而我们的http和https协议就是典型的应用层协议。

一、HTTP协议

1、概念

超文本传输协议(Hypertext Transfer Protocol,HTTP)是一个简单的请求-响应协议,它通常运行在TCP之上。它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。

2、URL

统一资源定位系统(uniform resource locator;URL)是因特网的万维网服务程序上用于指定信息位置的表示方法。

比如下面的这个URL:

协议名称:就是服务器所使用协议,我们平常所见到的就是HTTP协议或安全协议HTTPS。HTTPS是以安全为目标的HTTP通道,在HTTP的基础上通过传输加密和身份认证保证了传输过程的安全性(具体后面讲)。

域名:也就是我们常说的服务器IP地址。但是IP一般是不适合用户看的,所以就会转化成用户能够认出的名称。比如通过拼音baidu我们大概就能知道这是百度服务器下的内容。其实除了IP,还有一个应该是端口号,可是这里没有,因为端口号是众所周知的,所以一般不会显示地写在URL中。

带层次的文件路径:这就指明了用户想要访问的内容在服务器上的具体路径。访问服务器的目的是获取服务器上的某种资源,而服务器上的资源是保存在文件中的,所以通过前面的域名和端口已经能够找到对应的服务器进程了,此时要做的就是指明该资源所在的路径,就能找到资源所在的文件,获取资源了。

仔细观察你会发现,这里的路径分隔符是/,而不是\,这也就证明了实际很多服务都是部署在Linux上的。

二、HTTP协议格式

从报文的角度出发,http是基于行的文本协议。

1、请求协议格式

说明:

1、请求行。从左到右,请求方法,url连接,http协议版本(以空行隔开)。

请求方法: 

2、请求报头。请求报头中含有各种属性信息,比如,正文大小等。

3、空行:http协议通过空行来区分报头和有效载荷。

4、请求正文:通过请求报头得知其大小。

前面三部分是一般是HTTP协议自带的,是由HTTP协议自行设置的,而请求正文一般是用户的相关信息或数据,如果用户在请求时没有信息要上传给服务器,此时请求正文就为空字符串。

客户端在发起HTTP请求时告诉服务器自己所使用的http版本,此时服务器就可以根据客户端使用的http版本,为客户端提供对应的服务。

HttpServer服务器:

在网络协议栈中,应用层的下一层叫做传输层,而HTTP协议底层通常使用的传输层协议是TCP协议,因此我们可以用套接字编写一个TCP服务器,然后启动浏览器访问我们的这个服务器。

下面我们编写一个简单的TCP服务器,这个服务器要做的就是把浏览器发来的HTTP请求进行打印。

HttpServer.hpp:

#pragma once
#include <iostream>
#include "Sock.hpp"
#include <string>
#include <sys/types.h>
#include <sys/socket.h>
#include <signal.h>
#include <functional>

class HttpServer
{
public:
    using func_t = std::function<void(int)>;
    HttpServer(const uint16_t &port, func_t func) : port_(port), func_(func)
    {
        listen_ = sock_.Socket();
        sock_.Bind(listen_, port_);
        sock_.Listen(listen_);
    }

    void start()
    {
        signal(SIGCHLD, SIG_IGN);
        for (;;)
        {
            uint16_t client_port = 0;
            std::string client_ip;
            int sockfd = sock_.Accept(listen_, &client_ip, &client_port);
            if (sockfd < 0)
                continue;
            if (fork() == 0)
            {
                close(listen_);
                func_(sockfd);
                close(sockfd);
                exit(0);
            }
            close(sockfd);
        }
    }

    ~HttpServer()
    {
        if (listen_ >= 0)
            close(listen_);
    }

private:
    uint16_t port_;
    Sock sock_;
    int listen_;
    func_t func_;
};

Sock.hpp:

#pragma once
#include <iostream>
#include <string>
#include <cstdbool>
#include <cstring>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

class Sock
{
public:
    const static int gmv = 20;
    Sock()
    {
    }

    int Socket()
    {
        // 1.创建套接字
        int sock = socket(AF_INET, SOCK_STREAM, 0);
        if (sock < 0)
        {
            std::cout << "创建套接字失败!" << std::endl;
            exit(1);
        }
        std::cout << "创建套接字成功!" << std::endl;
        return sock;
    }

    void Bind(int sock, uint16_t port, std::string ip = "0.0.0.0")
    {
        // 2.进行绑定
        struct sockaddr_in src_server;
        bzero(&src_server, sizeof(src_server));
        src_server.sin_family = AF_INET;
        src_server.sin_port = htons(port);
        inet_pton(AF_INET, ip.c_str(), &src_server.sin_addr);
        socklen_t len = sizeof(src_server);
        if (bind(sock, (struct sockaddr *)&src_server, len) < 0)
        {
            std::cout << "绑定失败!" << std::endl;
            exit(2);
        }
        std::cout << "绑定成功!" << std::endl;
    }

    void Listen(int sock)
    {
        // 3.开始监听,等待连接
        if (listen(sock, gmv) < 0)
        {
            std::cout << "监听失败!" << std::endl;
            exit(3);
        }

        std::cout << "服务器监听成功!" << std::endl;
    }

    int Accept(int sock, std::string *ip, uint16_t *port)
    {
        // 4.获取链接
        struct sockaddr_in client_sock;
        socklen_t len = sizeof(client_sock);
        int serversock = accept(sock, (struct sockaddr *)&client_sock, &len);
        if (serversock < 0)
        {
            std::cout << "获取链接失败!" << std::endl;
            return -1;
        }
        if (port)
            *port = ntohs(client_sock.sin_port);
        if (ip)
            *ip = inet_ntoa(client_sock.sin_addr);
        return serversock;
    }
    ~Sock()
    {
    }
};

 HttpServer.cc:

#include <iostream>
#include <memory>
#include <sys/types.h>
#include <sys/socket.h>
#include "HttpServer.hpp"

void handerHttprequest(int sock)
{
    char buffer[10240];
    ssize_t s = recv(sock, buffer, sizeof(buffer) - 1, 0);
    if (s > 0)
    {
        buffer[s] = 0;
        std::cout << buffer << "---------------------\n"
                  << std::endl;
    }
}

static void usage(std::string proc)
{
    std::cout << "\n"
              << proc << " port"
              << std::endl;
}

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        usage(argv[0]);
        exit(0);
    }
    uint16_t Serverport = atoi(argv[1]);
    std::unique_ptr<HttpServer> Server(new HttpServer(Serverport, handerHttprequest));
    Server->start();
    return 0;
}

因为我们没有具体向服务器请求什么内容,所以并没有请求正文。 而请求报头当中确实全部都是以key: value形式按行陈列的各种请求属性。

上图是我使用我的手机进行访问服务器,在服务器端获得的请求。 

2、响应协议格式

HTTP响应由以下四部分组成:

~ 状态行:http版本 + 状态码 + 状态码描述
~ 响应报头:响应的属性,这些属性都是以key: value的形式按行陈列的。
~ 空行:遇到空行表示响应报头结束。同样通过空行来区分报头和有效载荷。
~ 响应正文:响应正文允许为空字符串,如果响应正文存在,则响应报头中会有一个Content-Length属性来标识响应正文的长度。比如服务器返回了一个html页面,那么这个html页面的内容就是在响应正文当中的。

下面我们构建一个HTTP响应给浏览器。我们将上面的handerHttprequest函数改为:

void handerHttprequest(int sock)
{
    char buffer[10240];
    ssize_t s = recv(sock, buffer, sizeof(buffer) - 1, 0);
    if (s > 0)
    {
        buffer[s] = 0;
        std::cout << buffer << "---------------------\n"
                  << std::endl;
    }

    std::string Response = "HTTP/1.1 200 OK\r\n";
    Response += "\r\n";
    Response += "<html><h3>hello HTTP</h3></html>";
    send(sock, Response.c_str(), Response.size(), 0);
}

url当中的/不能称之为我们的linux服务器上根目录,这个/表示的是web根目录,这个web根目录可以是你的机器上的任何一个目录,这个是可以自己指定的,不一定就是Linux的根目录。 我们一般访问网页,也就是访问web根目录下的某一个资源。/a/b/c/d.html就是web根目录下的某一个资源。

实际我们在进行网络请求的时候,如果不指明请求资源的路径,此时默认你想访问的就是目标网站的首页,也就是web根目录下的。

三、HTTP的请求方法

首先,我们介绍一个命令 telnet:该命令可以远程登录到某个服务器。

使用:telnet 服务器IP 端口号。

常用的请求方法:

方法说明
GET获取资源
POST传输实体主体
PUT传输文件
HEAD获得报文首部
DELETE删除文件
OPTIONS询问支持的方法
TRACE追踪路径
CONNECT要求用隧道协议连接代理
LINK建立和资源之间的联系
UNLINK断开连接关系

我们平时的上网行为其实一般就两种:从服务器端拿到资源,或者将客户端的数据提交到服务端,所以最常用的方法就是:GET和POST这两个方法。GET方法一般用于获取某种资源信息,而POST方法一般用于将数据上传给服务器。但实际我们上传数据时也有可以使用GET方法。

比如下面,我们使用telnet远程登陆百度主页,然后发送GET方法的请求:

我们就可以得到百度的主页内容:

 GET方法和POST方法的区别。

GET方法和POST方法都可以带参:GET方法是通过url传参的。而POST方法是通过正文传参的。使用POST方法传参更加私密,因为POST方法通过正文传参,不会将你的参数回显到url当中,此时也就不会被别人轻易看到。GET会将参数传给url,而url是能够被所有人看见的。

下面我们就来演示一下两者的区别。

首先,我们需要明白一个概念:表单——作用就是收集用户数据,并把数据推送给服务器。表单中的数据会作为HTTP请求的一部分被推送。

对于下面的淘宝网的登陆界面,我们可以查看其相关前端代码:

如果使用GET方法,那么淘宝账号和密码就会作为参数传给URL,也就是说用户可以在浏览器上方的网址栏的URL中看到账号和密码。而如果使用POST方法,那么淘宝账号和密码就会作为请求的正文,传给服务器,在URL中我们也就不会看见,所以POST更加私密。但是不代表就是安全的!要做到安全只能通过加密来完成。

POST方法能传递更多的参数,因为url的长度是有限制的,POST方法通过正文传参就可以携带更多的数据。

四、HTTP的状态码

类别原因短语
1XXInformational(信息性状态码)接收的请求正在处理
2XXSuccess(成功状态码)请求正常处理完毕
3XXRedirection(重定向状态码)需要进行附加操作以完成请求
4XXClient Error(客户端错误状态码)服务器无法处理请求
5XXServer Error(服务器错误状态码)服务器处理请求出错

我们平时常见的状态码:比如200(OK),404(Not Found),403(Forbidden 无请求权限),302(Redirect,重定向),504(Bad Gateway) 

Redirect,重定向状态码

重定向: 当我们对某些网页进行请求访问时,因为功能要求,我们跳转到去请求访问其他网页。

例如:我们在使用网页版的视频网站的时候,最先进入的是其首页。当我们想要登陆,点击登陆就会跳转到登陆页面,这是重定向。而当我们登陆成功后又会返回主页面,这也是重定向。

重定向可分为临时重定向和永久重定向,其中状态码301表示的就是永久重定向,而状态码302和307表示的是临时重定向。

下面我们就来演示一下重定向,我们直接修改HttpServer.cc:直接在报文中添加 "Location: https://www.qq.com/\r\n",将原来的页面重定向到qq网页。

#include <iostream>
#include <memory>
#include <sys/types.h>
#include <sys/socket.h>
#include "HttpServer.hpp"

void handerHttprequest(int sock)
{
    char buffer[10240];
    ssize_t s = recv(sock, buffer, sizeof(buffer) - 1, 0);
    if (s > 0)
    {
        buffer[s] = 0;
        std::cout << buffer << "---------------------\n"
                  << std::endl;
    }

    std::string Response = "HTTP/1.1 302 Found\r\n";
    Response += "<html><h3>hello world!</h3></html>";
    Response += "\r\n";
    Response += "Location: https://www.qq.com/\r\n";
    send(sock, Response.c_str(), Response.size(), 0);
}

static void usage(std::string proc)
{
    std::cout << "\n"
              << proc << " port"
              << std::endl;
}

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        usage(argv[0]);
        exit(0);
    }
    uint16_t Serverport = atoi(argv[1]);
    std::unique_ptr<HttpServer> Server(new HttpServer(Serverport, handerHttprequest));
    Server->start();
    return 0;
}

然后启动服务器,通过浏览器访问我们的网页。我们就发现直接跳转到了qq的网页。

下图是服务器获得的请求: 

五、HTTP常见的报头

HTTP常见的Header: 

1、Content-Type:数据类型(text/html等)。
2、Content-Length:正文的长度。
3、Host:客户端告知服务器,所请求的资源是在哪个主机的哪个端口上。
4、User-Agent:声明用户的操作系统和浏览器的版本信息。
5、Referer:当前页面是哪个页面跳转过来的。就是浏览器中的回退功能。
6、Location:搭配3XX状态码使用,告诉客户端接下来要去哪里访问。
7、Cookie:用于在客户端存储少量信息,通常用于实现会话(session)的功能。                    8、connection:表明客户端和服务器之间的连接是长连接还是短链接。

会话管理:

http是一种无状态协议。无状态:HTTP协议不会记录用户的上一次的请求。即其不会对用户的行为作任何的记录。

但是我们使用浏览器的时候发现并不是这样的。在实际中,一般网站都会记录下用户的状态。比如我们平时打开电脑,访问csdn的时候,由于我们之前已经登陆过,发现我们之后访问csdn的时候就不用再登陆了,csdn并没有要求我们再次输入账号和密码。

上面这种便捷的服务是通过cookie技术实现的,点击浏览器当中锁的标志就可以看到对应网站的各种cookie数据。

当我们第一次登录某个网站时,需要输入我们的账号和密码进行身份认证,此时如果服务器经过数据比对后判定你是一个合法的用户,就允许登陆。那么为了让你后续在进行某些网页请求时不用重新输入账号和密码,此时服务器就会进行Set-Cookie的设置。(Set-Cookie也是HTTP报头当中的一种属性信息)服务器会把用户的账号和密码等私密信息保存在浏览器客户端的cookie文件中。

当用户下次使用该浏览器访问时,cookie文件中的私密信息就会包含在HTTP请求中(也就是报头中的cookie字段),发送给服务器,进行身份验证。

可是,如果你浏览器当中保存的cookie信息被非法用户盗取了,那么此时这个非法用户就可以用你的cookie信息,非法用户不仅知道了你的私密信息,还可以以你的身份去访问你曾经访问过的网站。

所以,单纯的使用cookie是非常不安全的,因为此时cookie文件当中就保存的是你的私密信息,一旦cookie文件泄漏你的隐私信息也就泄漏。我们就要使用下面的策略来解决这个问题。

当我们第一次登录某个网站输入账号和密码后,服务器认证成功后会在服务端生成一个唯一的session id,这个session id与用户信息是不相关的。系统会将所有登录用户的session id值统一维护起来。

此时当认证通过后服务端在对浏览器进行HTTP响应时,就会将这个生成的session id返回给浏览器。浏览器收到响应后会自动提取出session id的值,将其保存在浏览器的cookie文件当中。后续访问该服务器时,对应的HTTP请求当中就会自动携带上这个session id。

而服务器识别到HTTP请求当中包含了session id,就会提取出这个session id,然后再到对应的结构当中进行对比,对比成功就说明这个用户是曾经登录过的,此时也就自动就认证成功了。

当然,这也并不是一定安全的,因为非法用户可以获取我们的session id,任然能够访问我们曾经访问过的网站。所以这只是相对安全的。

connection:

keep-alive:长连接。建立连接后,客户端可以不断的向服务器一次写入多个HTTP请求,而服务器在上层依次读取这些请求就行了,此时一条连接就可以传送大量的请求和响应,这就是长连接。长连接适用于需要频繁通信的场景。

close:短连接。短连接是在数据传送过程中,只在需要发送数据时建立一个连接,数据发送完成后,连接会被断开。这种连接方式适用于非实时通信场景,短连接的特点是每次通信都会建立新的连接,通信结束后,服务器和客户端会关闭连接,它不会长期占用通道。

六、HTTP和HTTPS

早期,我国的互联网行业刚刚兴起的时候,互联网所用的协议是HTTP协议,而HTTP无论是用GET方法还是POST方法传参,都是没有经过任何加密的。因此,HTTP协议在携带数据的时候是明文的,所以用户信息等私密数据很有可能会被不法分子获取,这样就非常不安全。而只有对数据进行加密后,我们才能在一定程度上保证用户数据的安全,所以后来就有了HTTPS协议。

1、HTTPS协议

HTTPS协议实际就是在应用层和传输层协议之间加了一层加密层(SSL&TLS),这层加密层本身也是属于应用层的。它会对用户的个人信息等私密信息进行各种程度的加密。HTTPS协议在交付数据时先把数据交给加密层,由加密层对数据加密后再交给传输层继续向下封装。

相同的,当对端从下向上交付的时候,传输层收到数据后,会先将数据交给加密层,由加密层对数据进行解密后再将数据交给应用层。

这样,即使不法分子在网络中拿到了数据后,拿到的也是加密后的数据,它无法解密,也就拿不到原文,这样就保护了用户的信息。

2、HTTPS的加密原理

1、基本概念

一般来说,我们可以将加密方法分为对称加密和非对称加密。

对称加密:也叫单密钥加密。采用单钥密码系统的加密方法,同一个密钥可以同时用作信息的加密和解密,这种加密方法称为对称加密。即加密和解密所用的密钥相同。

特点:加密速度快,加密效率高。

举例:假如我们现在有一个明文 a = 1234,密钥 key = 8888。我们使用异或方法对a进行加密:a^key得到密文b = 9834,然后再对密文b进行解密 b^key  = 1234,就得到了明文a。这就是一个简单的对称加密。

非对称加密:需要两个不同的密钥来进行加密和解密。一个是公开密钥(公钥),一个是私有密钥(私钥)。

特点:算法强度复杂,加密速度比对称加密慢很多。通过公钥对明文进行加密使其变成密文,通过私钥对密文进行解密使其变成明文(当然,也可以反过来使用:公钥解密形成明文,私钥加密形成密文)。

数据摘要:又称数据指纹,其基本原理就是利用单向散列函数(Hash函数)对信息进行运算,生成一串固定长度的数据摘要,不同的文本经过同种Hash形成的摘要一定是不同的,通常用来进行数据比对。注:并不是一种加密机制,摘要经过加密会得到数字签名。

2、加密原理

HTTPS所使用的加密原理是对称加密和非对称加密相结合的方法。

具体原理如下:

首先,客户端向服务端发起通信HTTPS请求,客户端和服务端进行密钥协商。服务端有自己的非对称密钥:公钥s和私钥s'。 服务端将公钥s发送给客户端,客户端拿到s后,自动形成对称密钥x。

然后,客户端使用公钥s对对称密钥x进行加密,接着将密文传送给服务端。服务端拿到密文后,使用私钥s'对密文进行解密,拿到对称密钥x。之后,客户端和服务端就通过对称密钥x进行通信。

好处:即使有不法人员在网络中拿到x加密后的密文,因为其没有私钥s',无法解密,所以也无法知道通信所使用的密钥x,也就无法解密经对称密钥x加密后的密文。这样就保证了服务端和客户端之间通信的安全。

但是,这也并不是一定安全的,如果在服务端和客户端进行密钥协商的时候,不法分子就开始攻击了,任然无法保证安全。如下图:

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CSDN如何转载他人文章(超简单)

经常遇到一篇很好的文章&#xff0c;但是CSDN没有转载功能&#xff0c;所以需要我们自己处理一下。以谷歌浏览器打开某篇文章为例 一、按F12打开开发者工具 二、复制转载文章内容 按Ctrlf查找content_views&#xff0c;找到这一行<div id"content_views" class&…

2024项目拆解日均引流100+精准创业粉,全程干货

详情介绍 2024年项目拆解引流高质量创业粉&#xff0c;全程干货单日轻松引流100&#xff0c;项目拆解类视频本身引流效果就非常不错&#xff0c;视频内容针对性强直击创业粉内心&#xff0c;获客非常有效。做好视频钩子&#xff0c;和后端承接&#xff0c;赚钱没那么难。 课程…

没有精益管理内容的数字化,会是成功的数字化吗?

精益管理与数字化的结合被认为是制造业和企业管理中的一种重要转型策略。精益管理注重消除浪费、提升效率和质量&#xff0c;而数字化则通过技术手段来实现这一目标&#xff0c;两者的结合能够带来更高效、更智能的生产和管理方式。 首先&#xff0c;精益管理的核心理念是价值…

什么是HTTPS证书?怎么免费申请?——值得收藏

SSL证书的核心功能在于保障互联网数据传输的安全性和网站身份的可靠性。它通过加密通信防止信息被窃取或篡改&#xff0c;同时验证网站的真实身份&#xff0c;有效抵御钓鱼攻击&#xff0c;增强用户信任。此外&#xff0c;使用SSL证书还有助于提升网站在搜索引擎中的排名&#…

Docker 入门篇(六)-- idea 打包 docker 镜像流程

环境准备&#xff1a; idea 环境&#xff1a;IntelliJ IDEA 2021.3.1 (Ultimate Edition)docker 版本&#xff1a;v. 26.1.0准备 springboot jar 文件 &#xff1a;target/DockerDemo-0.0.1-SNAPSHOT.jardocker 可视化管理工具 portainer &#xff1a;v2.6.0 一. 配置docker远…

前端面试题大合集3----网络篇

一、Http协议详解&#xff0c;http请求方式&#xff0c;http状态码 Http协议详解&#xff1a; 全称Hyper Text Transfer Protocol&#xff0c;即超文本传输协议&#xff0c;是互联网上应用最为广泛的一种网络传输协议。 是一个无状态的应用层协议&#xff0c;即不会保存客户…

【管理咨询宝藏92】国际咨询公司为大型药企数字化转型项目规划方案

本报告首发于公号“管理咨询宝藏”&#xff0c;如需阅读完整版报告内容&#xff0c;请查阅公号“管理咨询宝藏”。 【管理咨询宝藏92】国际咨询公司为大型药企数字化转型项目规划方案 【格式】PDF版本 【关键词】国际咨询公司、药企转型、数字化转型 【核心观点】 - 企业业务…

51-48 CVPR 2024 | Vlogger: make your dream a vlog 自编剧制作视频博客

24年1月&#xff0c;上海交大、上海人工智能实验室、中科院联合发布Vlogger&#xff1a;make your dream a vlog。该论文主要工作是生成超过5分钟的视频博客vlog。鉴于现有文本到视频T2V生成方法很难处理复杂的故事情节和多样化的场景&#xff0c;本文提出了一个名为Vlogger的通…

百度文库最新AI旋转验证码

上个月发现百度文库最新出了一个验证码&#xff0c;是AI生成的。内容每次可能都不一样&#xff0c;所以给识别造成 了很大困难。传统的比对放松完全失效。 一、介绍 这个是最近才出的最新验证码&#xff0c;内容主要以工厂、建筑、山峰、机器人、汽车、盆栽植物等为主。如下图…

Elasticsearch:如何使用 Java 对索引进行 ES|QL 的查询

在我之前的文章 “Elasticsearch&#xff1a;对 Java 对象的 ES|QL 查询”&#xff0c;我详细介绍了如何使用 Java 来对 ES|QL 进行查询。对于不是很熟悉 Elasticsearch 的开发者来说&#xff0c;那篇文章里的例子还是不能单独来进行运行。在今天的这篇文章中&#xff0c;我来详…

【DPU系列之】Bluefield 2 DPU卡的功能图,ConnectX网卡、ARM OS、Host OS的关系?(通过PCIe Switch连接)

核心要点&#xff1a; CX系列网卡与ARM中间有一个PCIe Swtich的硬件单元链接。 简要记录。 可以看到图中两个灰色框&#xff0c;上端是Host主机&#xff0c;下端是BlueField DPU卡。图中是BF2的图&#xff0c;是BF2用的是DDR4。DPU上的Connect系列网卡以及ARM系统之间有一个…

第一课为SimaPro的基本特征

问题&#xff1a; 咖啡机的设计中的环境影响指标。 step 1 点击Wizards&#xff0c;看到“Guided tour (with coffee)”。 在这个例子里&#xff0c; 定义了两种咖啡机&#xff1a; Sima型咖啡机 和 Pro型咖啡机&#xff0c; 具有以下规格&#xff1a; Sima型咖啡机 Pro型咖啡…

MySQL——Windows平台下MySQL安装与配置(一)MySQL安装

Windows平台下安装和配置 基于Windows平台的MySQL安装文件有两个版本&#xff0c;一种是以.msi作为后缀名的二进制分发版&#xff0c;一种是以.zip作为后缀的压缩文件。其中.msi的安装文件提供了图形化的安装向导&#xff0c;按照向导提示进行操作即可安装完成&#xff0c;.zip…

7-92 骨牌铺方格

在2n的一个长方形方格中&#xff0c;用一个12的骨牌铺满方格&#xff0c;输入n&#xff0c;输出铺放方案的总数。例如n3时&#xff0c;骨牌的铺放方案有3种&#xff0c;如下图所示。 输入格式: 测试数据有多组&#xff0c;处理到文件尾。每组测试输入一个整数n&#xff08;0&l…

【华为】AC直连二层组网隧道转发实验配置

【华为】AC直连二层组网隧道转发实验配置 实验需求拓扑配置AC数据规划表 AC的配置顺序AC1基本配置(二层通信)AP上线VAP组关联--WLAN业务流量 LSW1AR1STA获取AP的业务流量 配置文档 实验需求 AC组网方式&#xff1a;直连二层组网。 业务数据转发方式&#xff1a;隧道转发。 DHC…

[JUCE]从一个有关右值引用的bug,探幽移动语义

一、问题 当我尝试在\JUCE\extras\WindowsDLL\Builds\VisualStudio2022目录下编译JUCE库的时候&#xff0c;提示报错如下&#xff1a; 报错提示如下&#xff1a; 这里涉及到两个问题 一、这个std::move是干嘛用的 二、为什么这里会报错&#xff1f; 另外&#xff0c;我在实…

Mybatis进阶2

Mybatis进阶1-CSDN博客 Mybatis入门-CSDN博客 Mybatis入门2-CSDN博客 我们接下来要学习Mybatis的高级查询 我们先在数据库中准备我们需要的数据表 teacher表 课程表&#xff1a;与教师表是一对多的关系&#xff0c;所以有一个外键字段 学生表 由于学生表和课程表是多对多的…

Android selinux权限

一.SE 概述 SELinux 是由美国NSA&#xff08;国安局&#xff09;和 SCC 开发的 Linux的一个扩张强制访问控制安全模块。原先是在Fluke上开发的&#xff0c;2000年以 GNU GPL 发布。从 fedora core 2开始&#xff0c; 2.6内核的版本都支持SELinux。 在 SELinux 出现之前&#…

智慧公厕打造公共厕所智慧化管理模式

智慧公厕如何打造智慧化的管理模式&#xff1f;随着智能科技的快速发展&#xff0c;智慧公厕成为了城市管理的一项重要工作。智慧公厕的智能化管理不仅可以提升公厕的整体管理水平&#xff0c;还能为市民提供更加便捷、舒适的使用体验。本文将以智慧公厕源头实力厂家广州中期科…