HTTP协议初识·中篇

加上目录,会出现导向不正确的情况,可能是bug,目录一长就容易出错?

本篇主要讲解了:

        网页分离(网页代码和.c文件分离)

        html链接跳转

        网页添加图片

        确认并返回资源类型

        填写正文长度属性

        添加表单

        临时重定向

补充知识:

        前后端区别

        浏览器是如何显示页面的

        http各字段属性是什么意思

        提交给指定的路径有什么意义?

        http方法

        http状态码

        HTTP常见Header

        写入cookie信息

源码

承接上文

 HTTP协议初识·上篇_清风玉骨的博客-CSDN博客

第二点在上文中已经完成 

1:网页分离

网页分离1.0:404文件一定会存在

readFile函数1.1:读取文件中的内容

读取文件中的内容

 

404html文件

在vscode有快捷生成网页,!+  Tab键 

测试1:网页分离与404文件

成功

 

404访问

2:html链接跳转

2.0添加点击键与返回键

其实游览器的返回键可以直接使用,效果是一样的

测试2:返回键与404测试

返回键

404(返回时候不存在)

故意写错

别人的404网页

高级一点…… 

补充1:后端与前端区别做那些部分?

3:添加图片

测试3:图片测试

在wwwroot下创建一个image文件夹,把图片放进去就行了,这里不显示的原因估计是云服务器配置太低,导致图片加载不出来,因为这个.jpg的格式一般都比较大,这边测试用的是大概200kb的图片,果然配置低了点

补充2:浏览器是如何显示网页的?

        其实很简单,例如访问首页,就是把的全部资源下载下来,再组合显示过来就行了

        即用户看到的网页结果,可能是多个资源组合而成的!所以要获取一张网页效果,浏览器一定会发起多次http请求,这也是为什么会有高并发访问原因

4:如何正确返回资源类型?

为了返回正确的文件信息,我们得填写Content-Type来,让它不要一直指向首页,这里直接搜索对照表即可找到相应的对照

suffixToDesc函数4.1后缀分离函数

测试4:图片再测试

        不过通常这类的图片音频之类的比较吃资源的文件一般并不会直接放置在服务器里面,而是放置在别的专门放置资源的服务器上,为了进一步测试,我们还可以使用别人的图床中的图片,走别人的服务器

这一次很幸运的显示出来的,要注意很多网站的图片其实并不能直接使用,视乎做了处理,这里就不深加讨论了

5:添加正文长度

认识系统调用stat

测试5:添加正文长度

补充2:http各个字段的意思

6:添加表单

目前我们写的都是单向的,无法做到交互,因为使用的是,为了做到可以交互我们得引用表单

补充6.0:表单各部分意思

测试6:表单测试

GET方法:数据拼接到url后面

 

POST方法:数据放到正文部分

GET与POST方法只有私密性这一点不同

要想安全,得到https这一点我们后续再详谈

这里百度一下就是直接使用GET方法的

补充3:提交给指定的路径有什么意义?

补充4:使用unordered_map进行修改可以实现功能路由

这里是伪代码,仅提供思路

补充5:HTTP的方法

        其实除了GET和POST方法我们常使用,其他的方法我们使用的频率并不高,所以我们这里也就不详谈了,不是重点

所以GET和POST相比

如果你只想单纯的从远端获取资源:GET

如果你想要提参:GET/POST

无私密性:GET(简单)

私密性:POST

补充6:HTTP的状态码

        不过我们需要知道,虽然这些状态码是协议标准,不过解释权还是在写代码的人在操作,并且现在一般也不需要严格遵守,比如5开头的状态码我们平时就很少见,这一点想必大家都会意识到这一点,毕竟有点掉价,所以大部分服务器的错误,基本上都是返回4开头的状态码,因为这些错误要么就是很苛刻,要么就是大家都懂得,而且很重要的一点,根据5状态码的信息,一些非法分子可能就会利用这个错误码来进行攻击服务器,自然而然的这也成为了不成文规定了,基于这一点关于状态码与前端后端程序员对于状态码的认识注定是不一样的。

        不过现在的浏览器很智能了,它一般也不会通过状态码来规定网页显示内容,一般都是通过正文部分来显示的,这一点做得很好了

补充7:3开头重定向状态码

301 永久重定向  307 临时重定向 

        重定向可能提出来会有些不了解,其实我们很容易见到这个的,比如当年点击这个网站的时候,就会跳转来一个广告页面,这就是重定向的一种,这种一般是临时重定向,那边是金主就给那边定向导流,这种强制重定向就是用3开头的状态码来实现的

7:临时重定向

HTTP常见Header

Content-Type: 数据类型(text/html等)
Content-Length: Body的长度
Host: 客户端告知服务器, 所请求的资源是在哪个主机的哪个端口上;
User-Agent: 声明用户的操作系统和浏览器版本信息;
Referer: 当前页面是从哪个页面跳转过

Location: 搭配3xx状态码使用, 告诉客户端接下来要去哪里访问;
Cookie: 用于在客户端存储少量信息. 通常用于实现会话(session)的功能;

我们需要填写好Location这个报头属性

        静态网页 -- 目前我们所写的,因为C++并不适合写网页,动态网页专注与交互,用C++来做比较麻烦,所以我们C++程序员一般也不适用写复杂网页

修正bug代码 

之前的图片不显示bug已经修复,是之前的函数用错的原因,现在进行更正

 

 

        不过需要注意的是,这样会导致当资源不存在的时候,跳转的404页面将会跳转不成功,这个问题出现在添加的读取内容大小那边,因为当资源不存在的时候读取大小为-1(本程序设计),导致404页面读取失败,这里就不进行修正了,注意这一点就好了

源码

HttpServer.cc

#include "HttpServer.hpp"
#include <memory>using namespace std;
using namespace server;void Usage(std::string proc)
{cerr << "Usage:\n\t" << proc << " port\r\n\r\n";
}std::string suffixToDesc(const std::string suffix)
{std::string ct = "Content-Type: ";if (suffix == ".html")ct += "text/html";else if (suffix == ".jpg")ct += "application/x-jpg";ct += "\r\n";return ct;
}// 1. 服务器和网页分离,html
// 2. url -> / : web根目录
// 3. 我们要正确给客户端返回资源类型,我们首先要自己知道!所有的资源都有后缀!!!
bool Get(const HttpRequest &req, HttpResponse &resp)
{/*伪代码if(req.path == "test.py") 假如提交到一个python脚本{首先建立进程间通信, pipefork创建子进程, execl("/bin/puthon", test.py) 这样子进程就执行这个脚本父进程, 将req.parm 通过管道写过某些后端语言, C++并不适合写这个, 一般是指, python, java, php等这也是为什么服务器是C++写的,但是它的后端却是其他语言的原因}if(req.path == "/search"){req.parm使用我们自己写到C++方法,提供服务}*/// for testcout << "----------------------- http start ------------------------------------" << endl;cout << req.inbuffer << endl; // 暂时不做其他处理,直接打印出来看请求内容std::cout << "method: " << req.method << std::endl;std::cout << "url: " << req.url << std::endl;std::cout << "httpversion: " << req.httpversion << std::endl;std::cout << "path: " << req.path << std::endl;std::cout << "suffix: " << req.suffix << std::endl;std::cout << "size: " << req.size << "字节" << std::endl;cout << "------------------------ http end -------------------------------------" << endl;// std::string respheader = "Content-Type: text/html\r\n"; 不用这个了,固定死的std::string respline = "HTTP/1.1 200 OK\r\n";  // 其实这里的状态码也应该修改,不过这边就不做字符串拼接的过程了,就这样显示// std::string respline = "HTTP/1.1 307 Temporary Redirect\r\n";std::string respheader = suffixToDesc(req.suffix);// 往后每次http请求,都会自动携带曾经设置的所有cookie,帮服务器进行鉴权行为respheader += "Set-Cookie: name=1234567abcdefg; Max-Age=120\r\n"; // 有时间限制的120秒,时间到自动失效// respheader += "Location: https://www.bilibili.com/\r\n";std::string respblank = "\r\n"; // 空行// 网页 -- 自己写一个简单的, 不要在C++中写html,这里是测试,很不方便std::string body; // 从文件中来body.resize(req.size+1);if (!Util::readFile(req.path, (char*)body.c_str(), req.size)){Util::readFile(html_404, (char*)body.c_str(), req.size); //  这个操作一定能成功}/*测试 -- 这个代码会导致本地图片显示不出来,因为视频图片都是二进制的东西不能按行读取!要用readif (!Util::readFile(req.path, &body)){Util::readFile(html_404, &body); //  这个操作一定能成功}*//*这里没用了,修正还是有错误,错误转移了if (req.size > 0){respheader += "Content-Length: ";  添加正文的长度respheader += std::to_string(req.size);respheader += "\r\n";}*/// 直接拼接就可以了,本身很简单respheader += "Content-Length: ";respheader += std::to_string(body.size());respheader += "\r\n";resp.outbuffer += respline;resp.outbuffer += respheader;resp.outbuffer += respblank;cout << "----------------------- http response start ------------------------------------" << endl;std::cout << resp.outbuffer << std::endl;cout << "----------------------- http response end ------------------------------------" << endl;resp.outbuffer += body;return true;
}// ./httpServer 8080    -- 这里实际是80端口号,不过这里是为了测试就不用了,并且80也绑定不了,前一千多号基本内部资源无法绑定
int main(int argc, char *argv[])
{if (argc != 2){Usage(argv[0]);exit(0);}uint16_t port = atoi(argv[1]);unique_ptr<HttpServer> httpsvr(new HttpServer(Get, port));/*伪代码httpsvr->registerCb("/", Get); // 这就是 功能路由!httpsvr->registerCb("/search", Search);httpsvr->registerCb("/test.py", Other);*/httpsvr->initServer();httpsvr->start();return 0;
}

HttpServer.hpp

#pragma once#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
#include <functional>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
#include <pthread.h>
#include <unordered_map>#include "Protocol.hpp"namespace server
{enum{USAGE_ERR = 1,SOCKET_ERR,BIND_ERR,LISTEN_ERR};static const uint16_t gport = 8080;static const int gbacklog = 5; // 10、20、50都可以,但是不要太大比如5千,5万using func_t = std::function<bool(const HttpRequest &, HttpResponse &)>;    // 回调class HttpServer{public:HttpServer(func_t func, const uint16_t &port = gport) : _func(func), _listensock(-1), _port(port){}void initServer(){// 1. 创建socket文件套接字对象 -- 流式套接字_listensock = socket(AF_INET, SOCK_STREAM, 0); // 第三个参数默认 0if (_listensock < 0){exit(SOCKET_ERR);}// 2.bind绑定自己的网路信息 -- 注意包含头文件struct sockaddr_in local;memset(&local, 0, sizeof(local));local.sin_family = AF_INET;local.sin_port = htons(_port);      // 这里有个细节,我们会发现当我们接受数据的时候是不需要主机转网路序列的,因为关于IO类的接口,内部都帮我们实现了这一功能,这里不帮我们做是因为我们传入的是一个结构体,系统做不到local.sin_addr.s_addr = INADDR_ANY; // 接受任意ip地址if (bind(_listensock, (struct sockaddr *)&local, sizeof(local)) < 0){exit(BIND_ERR);}// 3. 设置socket 为监听状态 -- TCP与UDP不同,它先要建立链接之后,TCP是面向链接的,后面还会有“握手”过程if (listen(_listensock, gbacklog) < 0) // 第二个参数backlog后面再填这个坑{exit(LISTEN_ERR);}}/*伪代码void registerCb(std::string servicename, func_t cb) // 写一个注册方法{funcs.insert(std::make_pair(servicename, cb));}*/void HandlerHttp(int sock){// 1. 读到完整的http请求// 2. 反序列化// 3. 反序列化后得到httprequest, 回调填写httpresponse, 利用_func(req, resp)// 4. 序列化resp// 5. sendchar buffer[4096];HttpRequest req;HttpResponse resp;size_t n = recv(sock, buffer, sizeof(buffer) - 1, 0);   // 大概率我们直接能读取到完整的http请求if(n > 0){buffer[n] = 0;req.inbuffer = buffer;req.parse();// funcs[req.path](req, resp); 有了哈希表就不需要下面这一句了, 使用路径绑定服务, 这里并没有实现_func(req, resp);  // 可以根据bool返回值进行判断,这里就不判断了send(sock, resp.outbuffer.c_str(), resp.outbuffer.size(), 0);}}void start(){for (;;) // 一个死循环{// 4. server 获取新链接// sock 和 client 进行通信的fdstruct sockaddr_in peer;socklen_t len = sizeof(peer);int sock = accept(_listensock, (struct sockaddr *)&peer, &len);if (sock < 0){continue;}/* 这里直接使用多进程版的代码进行修改version 2 多进程版(2) -- 注意子进程会继承父进程的一些东西,父进程的文件操作符就会被子进程继承,即父进程的文件操作符那个数字会被继承下来,指向同一个文件,但是文件本身不会被拷贝一份也就是说子进程可以看到父进程创建的文件描述符sock和打开的listensock     */pid_t id = fork();if (id == 0) // 当id为 0 的时候就代表这里是子进程{/* 关闭不需要的文件描述符 listensock -- 子进程不需要监听,所以我们要关闭这个不需要的文件描述符即使这里不关,有没有很大的关系,但是为了防止误操作我们还是关掉为好   */close(_listensock);if (fork() > 0) exit(0); // 解决方法1: 利用孤儿进程特性HandlerHttp(sock);close(sock);exit(0);}/* 一定要关掉,否则就会造成文件描述符泄漏,但是这里的关掉要注意了,这里只是把文件描述符的计数-1子进程已经继承过去了,所以这里也可以看做,父进程立马把文件描述符计数-1,只有当子进程关闭的时候,这个文件描述符真正的被关闭了所以后面申请的链接使用的还是这个4号文件描述符,因为计算机太快了close(sock);   *//* father那么父进程干嘛呢? 直接等待吗? -- 显然不能,这样又会回归串行运行了,因为等待的时候会阻塞式等待且这里并不能用非阻塞式等待,因为万一有一百个链接来了,就有一百个进程运行,如果这里非阻塞式等待一但后面没有链接到来的话.那么accept这里就等不到了,这些进程就不会回收了 */// 不需要等待了 version 2waitpid(id, nullptr, 0);}}~HttpServer() {}private:int _listensock;uint16_t _port;func_t _func;// std::unordered_map<std::string, func_t> funcs;   构建一个哈希表用来实现功能路由};} // namespace server

makefile

cc=g++
httpserver:HttpServer.cc$(cc) -o $@ $^ -std=c++11.PHONY:clean
clean:rm -f httpserver

Protocol.hpp

#pragma once#include <iostream>
#include <string>
#include <vector>
#include <sstream> // 可以直接以空格作为分隔符来进行分割
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>#include "Util.hpp"const std::string sep = "\r\n";                  // 分隔符
const std::string default_root = "./wwwroot";    // web起始目录,前面的 ./ 加不加都可以
const std::string home_page = "index.html";      // 默认首页,任何服务器都会有这个默认首页
const std::string html_404 = "wwwroot/404.html"; // 这个文件一定会存在class HttpRequest
{
public:HttpRequest() {}~HttpRequest() {}void parse() // 解析{// 1. 从inbuffer中拿到第一行,分隔符\r\nstd::string line = Util::getOneline(inbuffer, sep);if (line.empty())return;// 2. 从请求行中提取三个字段 -- 下面放开的三个std::cout << "line: " << line << std::endl; // 打印出来显示一下std::stringstream ss(line);                 // 可以直接以空格作为分隔符来进行分割ss >> method >> url >> httpversion;/*2.1 /search?name=zhangsan&pwd=123456我们首先通过 ? 将左右进行分离如果是POST方法,本来就是分离的!左边path, 右边parm*/// 3. 添加web默认路径path = default_root; // 未来可以进行修改  变成 ./wwwrootpath += url;         // 到这一步之后就会  变成 ./wwwroot/a/b/c.html// 未来访问路径都会从这个路径下开始访问// 这边会遇到一个问题,当url是一个 / 的时候就不行,拼接的时候会变成 ./wwwroot/ 没有具体目标if (path[path.size() - 1] == '/')path += home_page; // 加一个判断就行了// 4. 获取path对应的资源后缀// ./wwwroot/index.html// ./wwwroot/test/a.html// ./wwwroot/image/宇宙.jpgauto pos = path.rfind(".");if (pos == std::string::npos)suffix = ".html";elsesuffix = path.substr(pos); // 截取到末尾// 5. 得到资源的大小struct stat st;int n = stat(path.c_str(), &st);// 这个系统调用会自动填充字段if(n == 0) size = st.st_size;   // 成功返回 0else size = -1;}public:std::string inbuffer;/*  我们可以细分许多字段,当需要什么就可以添加什么,这里为了简洁就不做这些工作了std::string reqline; // 请求行std::vector<std::string> reqheader; // 请求报头std::string body;   // 请求正文*/std::string method;      // 请求方法std::string url;         // 网址std::string httpversion; // 请求版本std::string path;        // web默认路径std::string suffix;      // 文件后缀int size;                // 正文的长度,把请求的资源的大小返回// std::string parm;        伪代码,用于放置 ? 右边的数据
};class HttpResponse
{
public:std::string outbuffer;
};

Util.hpp

#pragma once#include <iostream>
#include <string>
#include <fstream>class Util
{
public:// XXXX XXX XXX\r\nYYYYY  -- 格式// 第二个参数是分隔符,暴露在外部,让外部传进来static std::string getOneline(std::string &buffer, const std::string &sep) // 类内静态方法可以直接使用 -- 为了方便写,就定义成静态的{auto pos = buffer.find(sep);if (pos == std::string::npos)return "";                           // 没有找到分隔符std::string sub = buffer.substr(0, pos); // [ ) 左闭右开 拿到这一行字段// buffer.erase(0, sub.size() + sep.size());   删除这一行return sub;}static bool readFile(const std::string resource, char *buffer, int size) // 视频图片都是二进制的东西不能按行读取!{               std::ifstream in(resource, std::ios::binary);  // 按照二进制的方式读取文件内容if (!in.is_open()) return false; // resource not foundin.read(buffer, size);  in.close();return true;}/*测试 -- 这个代码会导致本地图片显示不出来,因为视频图片都是二进制的东西不能按行读取!要用readstatic bool readFile(const std::string resource, std::string *out) // 视频图片都是二进制的东西不能按行读取!{               std::ifstream in(resource, std::ios::binary);  // 按照二进制的方式读取文件内容if (!in.is_open()) return false; // resource not foundstd::string line;while (std::getline(in, line)){*out += line;}in.close();return true;*/
};

其他文件内容自行添加即可,这里为了简便篇幅就不粘贴了

未完持续更新中……

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

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

相关文章

06-限流策略有哪些,滑动窗口算法和令牌桶区别,使用场景?【Java面试题总结】

限流策略有哪些&#xff0c;滑动窗口算法和令牌桶区别&#xff0c;使用场景&#xff1f; 常见的限流算法有固定窗口、滑动窗口、漏桶、令牌桶等。 6.1 固定窗口 概念&#xff1a;固定窗口&#xff08;又称计算器限流&#xff09;&#xff0c;对一段固定时间窗口内的请求进行…

通过ref 操作dom , 点击按钮后跳转到页面指定图片位置

滚动图片到视图 定义了一个名为 scrollToIndex 的函数&#xff0c;它接受一个参数 index。当按钮被点击时&#xff0c;这个函数会被调用&#xff0c;并根据传入的 index 值来滚动到对应的图片。 以 alt 来标记图片位置 alt“Tom” import { useRef } from "react";c…

国标视频云服务EasyGBS国标视频平台迁移服务器后无法启动的问题解决方法

国标视频云服务EasyGBS支持设备/平台通过国标GB28181协议注册接入&#xff0c;并能实现视频的实时监控直播、录像、检索与回看、语音对讲、云存储、告警、平台级联等功能。平台部署简单、可拓展性强&#xff0c;支持将接入的视频流进行全终端、全平台分发&#xff0c;分发的视频…

使用DOSBOX运行TurboC2,TC2使用graphics库绘图

Turbo C是由美国Borland公司开发的一套C语言程序开发工具&#xff0c;Borland公司是一家专门从事软件开发、研制的大公司。该公司相继推出了一套Turbo系列软件&#xff0c;如Turbo BASIC、Turbo Pascal、Turbo Prolog&#xff0c;这些软件很受用户欢迎 [1] 。 Turbo C集成了程序…

2022年06月 C/C++(七级)真题解析#中国电子学会#全国青少年软件编程等级考试

C/C++编程(1~8级)全部真题・点这里 第1题:有多少种二叉树 输入n(1<n<13),求n个结点的二叉树有多少种形态 时间限制:1000 内存限制:65536 输入 整数n 输出 答案 样例输入 3 样例输出 5 这个问题可以使用动态规划的方法来解决。我们可以定义一个数组dp,其中dp[i]表…

北京APP外包开发需要注意的问题

开发APP的过程中&#xff0c;由于开发APP需要投入大量的时间、精力和资源&#xff0c;所以在开始前一定要做好充足的准备和规划。您需要注意以下重点&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1…

三相PMSM的坐标变换

三相PMSM的坐标变换 三相PMSM的数学模型具有复杂性和耦合性的多变量系统。因此需要对其进行降阶和解耦变换。 Vα&#xff0c;Vb&#xff0c;Vc是自然坐标系。 Vα&#xff0c;Vβ是静止坐标系。 Vd&#xff0c;Vq是同步旋转坐标系。 自然坐标系 三相永磁同步电机的驱动电路…

计算机毕设之基于python+django+mysql的影片数据爬取与数据分析(包含源码+文档+部署教程)

影片数据爬取与数据分析分为两个部分&#xff0c;即管理员和用户。该系统是根据用户的实际需求开发的&#xff0c;贴近生活。从管理员处获得的指定账号和密码可用于进入系统和使用相关的系统应用程序。管理员拥有最大的权限&#xff0c;其次是用户。管理员一般负责整个系统的运…

使用maven创建springboot项目

创建maven快速启动项目 命令行或者idea、eclipse快捷创建也可以 pom.xml下project项目下导入springboot 父工程 <!--导入springboot 父工程--> <parent><artifactId>spring-boot-starter-parent</artifactId><groupId>org.springframework.bo…

CSAPP的Lab学习——AttackLab

文章目录 前言一、阶段一攻击二、阶段二攻击三、阶段三攻击四、阶段四攻击五、阶段五攻击总结 前言 一个本硕双非的小菜鸡&#xff0c;备战24年秋招。刚刚看完CSAPP&#xff0c;真是一本神书啊&#xff01;遂尝试将它的Lab实现&#xff0c;并记录期间心酸历程。 代码下载 官方…

thinkPHP项目搭建

1 宝塔添加站点 &#xff08;1&#xff09;打开命令提示行&#xff0c;输入以下命令&#xff0c;找到hosts文件。 for /f %P in (dir %windir%\WinSxS\hosts /b /s) do copy %P %windir%\System32\drivers\etc & echo %P & Notepad %P &#xff08;2&#xff09;添加域…

html2canvas 截图空白 或出现toDataURL‘ on ‘HTMLCanvasElement或img标签没截下来 的所有解决办法

1.如果截图空白&#xff1a; 1.1以下的参数是必须要有的。 width: shareContent.offsetWidth, //设置canvas尺寸与所截图尺寸相同&#xff0c;防止白边height: shareContent.offsetHeight, //防止白边logging: true,useCORS: true,x:0,y:0,2&#xff0c;如果出现了报错 toData…

成集云 | 多维表格自动化管理jira Server项目 | 解决方案

源系统成集云目标系统 方案介绍 基于成集云集成平台&#xff0c;在多维表格中的需求任务信息自动创建、更新同步至 Jira Server 的指定项目中&#xff0c;实现多维表格中一表管理 Jira Server 中的项目进度。 维格表是一种新一代的团队数据协作和项目管理工具&…

基于深度学习网络的人员吸烟行为检测算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 clc; clear; close all; warning off; addpath(genpath(pwd)); rng(default)load FRCNN.mat I…

jmeter 准确的吞吐量定时器 Precise Throughput Timer

准确的吞吐量定时器使用实例&#xff1a; 说明&#xff1a;配置10个线程&#xff0c;每个线程请求200次&#xff0c;通过准确地屯托梁定时器模拟QPS为20的场景 配置测试接口参考链接 配置jmeter测试脚本&#xff0c;主要关注准确的吞吐量定时器参数配置 目延迟线程已确保目标吞…

Mariadb高可用(四十)

目录 一、概述 &#xff08;一&#xff09;概念 &#xff08;二&#xff09;组成 &#xff08;三&#xff09;特点 &#xff08;四&#xff09;工作原理 二、实验要求 三、构建MHA &#xff08;一&#xff09;ssh免密登录 &#xff08;二&#xff09;安装mariadb数据库…

python技术面试题合集(二)

python技术面试题 1、简述django FBV和CBV FBV是基于函数编程&#xff0c;CBV是基于类编程&#xff0c;本质上也是FBV编程&#xff0c;在Djanog中使用CBV&#xff0c;则需要继承View类&#xff0c;在路由中指定as_view函数&#xff0c;返回的还是一个函数 在DRF中的使用的就是…

内网隧道代理技术(二十一)之 CS工具自带中转技术上线不出网机器

CS工具自带上线不出网机器 如图A区域存在一台中转机器,这台机器可以出网,这种是最常见的情况。我们在渗透测试的过程中经常是拿下一台边缘机器,其有多块网卡,边缘机器可以访问内网机器,内网机器都不出网。这种情况下拿这个边缘机器做中转,就可以使用CS工具自带上线不出网…

windows-nessus安装

1、下载 路径&#xff1a;Download Tenable Nessus | Tenable 2、获取active code 路径&#xff1a;Tenable Nessus Essentials Vulnerability Scanner | Tenable 3、安装 challenge code:上图马赛克位置 active code:获取active code第二张图片的马赛克位置 4、激活 5、安装…

word中标题及公式自动编号

word中公式自动编号 1. 实现目标2. 详细步骤2.1 添加自动编号功能2.2 输入标题并编号2.3 新建公式2.3.1 编辑公式2.3.4 公式编号的交叉引用2.3.5 公式位置变动以及更新正文中的编号 在word中自动编号公式一直是一个老大难问题&#xff0c;现在通过总结网友们提供的方法&#xf…