HTTP(网络)

news2024/11/30 9:39:43

目录

1.Http的基本代码

1.1 HttpServer.hpp

1.2 简单测试一下

 1.3 用telnet测试一下

1.4 用浏览器访问

1.5 返回相应的过程(网页版本)​编辑

1.5.1 再次用浏览器访问

1.6 返回相应的过程(文件版本)

 1.6.1网页

 1.6.2 测试

1.7 反序列化截取

1.7.1 解析第一行 vector 0号下标里的字符串

1.7.1.1 stringstream分割符号

1.7.1.2 首页的设置 

1.7.2 访问别的网页(这里有3张网页 )

1.8 跳转网络链接​编辑

1.8.1 跳转到自己创建的网页

2.Http的细节字段

3.HTML 表单,输入账号和密码

3.1 get方法(不私密)

3.2 post方法

4. HTTP常见的Header​编辑

5.长短链接

5.1 短连接(HTTP 1.0)

C/C++ 中的短连接示例:

5.2 长连接(HTTP 1.1)

C/C++ 中的长连接示例:

5.3 关键区别总结

5.4 长短连接的选择

6.图片

​编辑

7.cookie文件(记住密码)

8.HTTP协议

8.1 认识URL(网址)

8.2 urlencode和urldecode

9.HTTP协议格式

10.HTTP的方法

11.HTTP的状态码

12.HTTP常见Header

13.最简单的HTTP服务器

抓包工具 

1.Http的基本代码

1.1 HttpServer.hpp

#pragma once
#include <iostream>
#include <string>
#include <pthread.h>
#include "Socket.hpp"
#include "logs/ljwlog.h"

using namespace std;
static const int dafaultport = 8080;

struct ThreadData
{
    int sockfd;
};

class HttpServer
{
public:
    HttpServer(uint16_t port = dafaultport):port_(port)
    {}
    bool Start()
    {
        listensock_.Socket();
        listensock_.Bind(port_);
        listensock_.Listen();
        for(;;)
        {
            string clientip;
            uint16_t clientport;
            int sockfd = listensock_.Accept(&clientip, &clientport);
            pthread_t tid;

            ThreadData *td = new ThreadData();
            td->sockfd = sockfd;
            pthread_create(&tid, nullptr, ThreadRun, td);
        }
    }

    //把收到的信息打印出来
    static void *ThreadRun(void *args)
    {
        pthread_detach(pthread_self());
        ThreadData *td = static_cast<ThreadData*>(args);
        char buffer[10240];
        //跟read用法很像
        ssize_t n = recv(td->sockfd, buffer, sizeof(buffer), 0);
        if(n > 0)
        {
            buffer[n] = 0;
            cout<< buffer;
        }
        close(td->sockfd);
        delete td;
        return nullptr;
    }

    ~HttpServer()
    {}
private:
    uint16_t port_;
    Sock listensock_;
};

1.2 简单测试一下

 1.3 用telnet测试一下

1.4 用浏览器访问

1.5 返回相应的过程(网页版本)

1.5.1 再次用浏览器访问

1.6 返回相应的过程(文件版本)

 1.6.1网页

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" const="width=device-width,initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>hello world</h1>
</body>
</html>

 1.6.2 测试

更改一下写的网页,服务器不用关,浏览器刷新一下就可以

1.7 反序列化截取

1.7.1 解析第一行 vector 0号下标里的字符串

 

 

1.7.1.1 stringstream分割符号

stringstream流式分隔符:stringstream - C++ Reference (cplusplus.com)

1.7.1.2 首页的设置 

1.7.2 访问别的网页(这里有3张网页 )

先开启服务器

1.8 跳转网络链接

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" const="width=device-width,initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>hello world</h1>
    <h1>hello world</h1>
    <h1>hello world</h1>
    <h1>hello world</h1>
    <h1>hello world</h1>
    <h1>hello world</h1>

    <a href="https://blog.csdn.net/2401_83427936?spm=1000.2115.3001.5343">Ljw的博客链接</a>
</body>
</html>

1.8.1 跳转到自己创建的网页

2.Http的细节字段

3.HTML 表单,输入账号和密码

在这之间输入

HTML <form> 标签_w3cschool

3.1 get方法(不私密)

get后会把自己输入的账号密码放进链接后面了 

3.2 post方法

4. HTTP常见的Header

5.长短链接

在 HTTP协议 中,长连接和短连接的概念主要体现在连接的持久性上。具体来说,HTTP协议的长短连接关系到客户端和服务器之间的连接是否保持持久,连接是否在多个请求之间复用。

5.1 短连接(HTTP 1.0)

在HTTP/1.0中,默认情况下每个请求都建立一个新的连接,通信完成后连接就会立即关闭。这种方式被称为 短连接。每当客户端发起一个HTTP请求时,服务器会为这个请求创建一个新的TCP连接,并在响应发送完毕后立即关闭这个连接。对于每个请求和响应,都会有一次建立连接、传输数据和断开连接的过程。

短连接的特点:

  • 每个请求都需要建立新的TCP连接。
  • 每次请求响应后,连接都会被关闭。
  • 适用于请求量不大的场景,因为每次建立和断开连接会带来一定的性能开销。
C/C++ 中的短连接示例:

假设你使用C/C++编写一个HTTP客户端发起HTTP请求并接收响应:

#include <iostream>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>

#define PORT 80

int main() {
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) {
        std::cerr << "Socket creation failed!" << std::endl;
        return -1;
    }

    sockaddr_in server_addr;
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(PORT);
    server_addr.sin_addr.s_addr = inet_addr("93.184.216.34");  // example.com IP

    if (connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
        std::cerr << "Connection failed!" << std::endl;
        return -1;
    }

    const char *request = "GET / HTTP/1.0\r\nHost: example.com\r\n\r\n";
    send(sockfd, request, strlen(request), 0);

    char buffer[1024];
    int bytes_received = recv(sockfd, buffer, sizeof(buffer) - 1, 0);
    buffer[bytes_received] = '\0';

    std::cout << "Response:\n" << buffer << std::endl;

    close(sockfd);  // Connection is closed after response
    return 0;
}

在这个短连接示例中,我们使用HTTP/1.0协议,每次请求完毕后,TCP连接会立即关闭。

5.2 长连接(HTTP 1.1)

HTTP/1.1引入了 长连接(Keep-Alive) 的概念,在这种模式下,连接不会在每个请求后关闭,而是保持打开状态,可以复用相同的连接来处理多个请求。这意味着客户端和服务器之间的连接可以用于多个请求和响应,直到明确关闭连接。

默认情况下,HTTP/1.1会使用长连接,但可以通过设置请求头 Connection: close 来显式关闭连接。

长连接的特点:

  • 连接在多个请求/响应之间保持活跃。
  • 节省了每次请求建立和关闭连接的开销,适用于需要频繁通信的场景。
  • 服务器会在一定时间内保持连接,如果长时间没有请求,连接会被关闭。
C/C++ 中的长连接示例:
#include <iostream>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>

#define PORT 80

int main() {
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) {
        std::cerr << "Socket creation failed!" << std::endl;
        return -1;
    }

    sockaddr_in server_addr;
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(PORT);
    server_addr.sin_addr.s_addr = inet_addr("93.184.216.34");  // example.com IP

    if (connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
        std::cerr << "Connection failed!" << std::endl;
        return -1;
    }

    // Send multiple requests over the same connection
    const char *request1 = "GET / HTTP/1.1\r\nHost: example.com\r\nConnection: keep-alive\r\n\r\n";
    send(sockfd, request1, strlen(request1), 0);

    char buffer[1024];
    int bytes_received = recv(sockfd, buffer, sizeof(buffer) - 1, 0);
    buffer[bytes_received] = '\0';

    std::cout << "Response 1:\n" << buffer << std::endl;

    const char *request2 = "GET /about HTTP/1.1\r\nHost: example.com\r\nConnection: keep-alive\r\n\r\n";
    send(sockfd, request2, strlen(request2), 0);

    bytes_received = recv(sockfd, buffer, sizeof(buffer) - 1, 0);
    buffer[bytes_received] = '\0';

    std::cout << "Response 2:\n" << buffer << std::endl;

    close(sockfd);  // Connection can be kept alive, but we close it here
    return 0;
}

在这个长连接的例子中,客户端向服务器发送两个HTTP请求,两个请求共享同一个TCP连接,直到手动关闭连接。通过在请求头中加入 Connection: keep-alive,客户端表明希望连接保持活跃。

5.3 关键区别总结

  • 短连接(HTTP/1.0):每个HTTP请求都建立一个新的TCP连接,通信结束后立即关闭,适用于请求量不大的情况。
  • 长连接(HTTP/1.1):连接在多个请求之间保持活跃,可以复用连接,直到服务器或客户端明确关闭连接,适用于需要频繁通信的场景。

5.4 长短连接的选择

  • 对于HTTP/1.0,通常使用短连接,尤其是在每个请求相对独立时。
  • 对于HTTP/1.1,长连接更为常见,尤其是在需要频繁请求或维持长期连接的场景(如实时应用、文件下载、网页加载等)。

长连接有助于减少连接的建立与关闭的开销,提高通信效率,尤其是在大量小请求的场景中,而短连接则适合一次性的请求和响应模式。

6.图片

文件后缀

7.cookie文件(记住密码)

文件级:可以记住一段时间

内存级:关闭就忘记

8.HTTP协议

虽然我们说, 应用层协议是我们程序猿自己定的.

但实际上, 已经有大佬们定义了一些现成的, 又非常好用的应用层协议, 供我们直接参考使用. HTTP(超文本传输协议)

就是其中之一.

8.1 认识URL(网址)

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

8.2 urlencode和urldecode

像 / ? : 等这样的字符, 已经被url当做特殊意义理解了. 因此这些字符不能随意出现.

比如, 某个参数中需要带有这些特殊字符, 就必须先对特殊字符进行转义.

转义的规则如下:

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

例如:

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

工具:URL 编码和解码 - 在线 (urlencoder.org)

9.HTTP协议格式

HTTP请求

  • 首行: [方法] + [url] + [版本]
  • Header: 请求的属性, 冒号分割的键值对;每组属性之间使用\n分隔;遇到空行表示Header部分结束
  • Body: 空行后面的内容都是Body. Body允许为空字符串. 如果Body存在, 则在Header中会有一个Content-Length属性来标识Body的长度;

HTTP响应

  • 首行: [版本号] + [状态码] + [状态码解释]
  • Header: 请求的属性, 冒号分割的键值对;每组属性之间使用\n分隔;遇到空行表示Header部分结束
  • Body: 空行后面的内容都是Body. Body允许为空字符串. 如果Body存在, 则在Header中会有一个Content-Length属性来标识Body的长度; 如果服务器返回了一个html页面, 那么html页面内容就是在body中.

10.HTTP的方法

其中最常用的就是GET方法和POST方法.

11.HTTP的状态码

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

12.HTTP常见Header

  • Content-Type: 数据类型(text/html等)
  • Content-Length: Body的长度
  • Host: 客户端告知服务器, 所请求的资源是在哪个主机的哪个端口上;
  • User-Agent: 声明用户的操作系统和浏览器版本信息;
  • referer: 当前页面是从哪个页面跳转过来的;
  • location: 搭配3xx状态码使用, 告诉客户端接下来要去哪里访问;
  • Cookie: 用于在客户端存储少量信息. 通常用于实现会话(session)的功能;

13.最简单的HTTP服务器

实现一个最简单的HTTP服务器, 只在网页上输出 "hello world"; 只要我们按照HTTP协议的要求构造数据, 就很容易 能做到;

HttpServer.cc

#include "HttpServer.hpp"
#include<memory>
#include<iostream>

using namespace std;
void Usage(const string& proc)
{
    cout<<"\nUsage" << proc << "port\n\n" <<endl;
}

int main(int argc, char* argv[])
{
    if(argc != 2)
    {
        Usage(argv[0]);
        exit(0);   
    }
    uint16_t port = stoi(argv[1]);
    unique_ptr<HttpServer> svr(new HttpServer(port));
    svr->Start();

    return 0;
}

HttpServer.hpp

#pragma once
#include <iostream>
#include <string>
#include <pthread.h>
#include <pthread.h>
#include <sstream>
#include <vector>
#include "Socket.hpp"
#include "logs/ljwlog.h"

using namespace std;
static const int dafaultport = 8080;
const string wwwroot = "./wwwroot";//web根目录
const string sep = "\r\n";
//首页
const string homepage = "index.html";

class ThreadData
{
public:
    ThreadData(int fd): sockfd(fd)
    {}

public:
    int sockfd;
};

class HttpRequest
{
public:
    //反序列化  这里把一个字符串变成多个字符串
    void Deserialize(string req)
    {
        while(true)
        {
            //找一行移动一行
            //                  分隔符
            size_t pos = req.find(sep);
            if(pos == string::npos)
            {
                break;
            }
            string temp = req.substr(0, pos);
            //读到空行就直接跳出
            if(temp.empty()) break;
            req_header.push_back(temp);
            req.erase(0, pos + sep.size());
        }
        text = req;
    }

    void DebugPrint()
    {
        cout<<"-----------------------"<<endl;
        for(auto& line:req_header)
        {
            cout<< line << "\n\n";
        }

        cout<< "method: " << method << endl;
        cout<< "url" << url <<endl;
        cout<< "http_version" << http_version <<endl;

        cout << text;
    }
    //解析第一行 vector 0号下标里的字符串
    void Parse()
    {
        stringstream ss(req_header[0]);
        ss >> method >> url >> http_version;
        file_path = wwwroot; //
        if(url == "/" || url == "/index.html")
        {
            file_path += "/";
            file_path += homepage;//    ./wwwroot/index.html
        }
        else
        {   
            file_path += url;// /a/b/c/d.html->./wwwroot/a/b/c/d.html   
        }
    }

public:
    vector<string> req_header;//把每一行push到req_header
    string text;//正文

    //解析后的结果  vector 0号下标里的字符串
    string method;
    string url;
    string http_version;
    string file_path;
};

class HttpServer
{
public:
    HttpServer(uint16_t port = dafaultport):port_(port)
    {}
    bool Start()
    {
        listensock_.Socket();
        listensock_.Bind(port_);
        listensock_.Listen();
        for(;;)
        {
            string clientip;
            uint16_t clientport;
            int sockfd = listensock_.Accept(&clientip, &clientport);
            if(sockfd < 0) continue;
            pthread_t tid;

            ThreadData *td = new ThreadData(sockfd);
            pthread_create(&tid, nullptr, ThreadRun, td);
        }
    }

    static string ReadHtmlContent(const string& htmlpath)
    {
        ifstream in(htmlpath);
        if(!in.is_open()) return "404";

        string content;
        string line;
        while(getline(in, line))
        {
            content += line;
        }
        in.close();
        return content;
    }

    static void HandlerHttp(int sockfd)
    {
        char buffer[10240];
        //跟read用法很像
        ssize_t n = recv(sockfd, buffer, sizeof(buffer), 0);
        if(n > 0)
        {
            buffer[n] = 0;
            cout<< buffer; //假设我们读到的是一个完整的请求,独立的Http请求
            HttpRequest req;
            req.Deserialize(buffer);
            req.Parse();//解析


            //req.DebugPrint();


            // //返回相应的过程
            string text = ReadHtmlContent(req.file_path);

            string response_line = "HTTP/1.0 200 OK\r\n ";
            string response_header = "Content-Length ";
            response_header = to_string(text.size());
            response_header += "\r\n";
            string blank_line = "\r\n";

            string response = response_line;
            response += response_header;
            response += blank_line;
            response += text;
            //和write类似
            send(sockfd, response.c_str(), response.size(), 0);
        }
        close(sockfd);

    }

    //把收到的信息打印出来
    static void *ThreadRun(void *args)
    {
        pthread_detach(pthread_self());
        ThreadData *td = static_cast<ThreadData*>(args);
        HandlerHttp(td->sockfd);
        delete td;
        return nullptr;
    }

    ~HttpServer()
    {}
private:
    uint16_t port_;
    Sock listensock_;
};

makefile

httpServer:HttpServer.cc
	g++ -g -o $@ $^ -std=c++11 -lpthread
.PHONT:clean
clean:
	rm -f httpServer

Socket.hpp

#pragma once
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <pthread.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <cstring>
#include "./logs/ljwlog.h"

using namespace std;

enum
{
    SocketErr = 2,
    BindErr,
    ListenErr
};
const int backlog = 10;
class Sock
{
public:
    Sock()
    {
    }
    ~Sock()
    {
    }

public:
    void Socket() // 创建套接字的接口
    {
        sockfd_ = socket(AF_INET, SOCK_STREAM, 0); // 流式套接字  第二个参数是协议类型
        if (sockfd_ < 0)
        {
            FATAL("Socket errno,error:%d,errstring:%s", errno, strerror(errno));
            exit(SocketErr);
        }
    }
    void Bind(uint16_t port) // 绑定的接口
    {
        struct sockaddr_in local;
        memset(&local, 0, sizeof(local));
        local.sin_family = AF_INET;
        local.sin_port = htons(port);       // 主机转网络
        local.sin_addr.s_addr = INADDR_ANY; // ip默认0.0.0.0
        if (bind(sockfd_, (struct sockaddr *)&local, sizeof(local)) < 0)
        {
            FATAL("Bind errno,error:%d,errstring:%s", errno, strerror(errno));
            exit(BindErr);
        }
    }
    void Listen() // 监听状态的接口
    {
        if (listen(sockfd_, backlog) < 0)
        {
            FATAL("Listen errno,error:%d,errstring:%s", errno, strerror(errno));
            exit(ListenErr);
        }
    }
    //              知道谁链接的我
    int Accept(string *clientip, uint16_t *clientport) // 获取连接的接口
    {
        struct sockaddr_in peer; // 远端的意思
        socklen_t len = sizeof(peer);
        int newfd = accept(sockfd_, (struct sockaddr *)&peer, &len);
        if (newfd < 0)
        {
            WARN("accept error, %s: %d", strerror(errno), errno);
            return -1;
        }
        // 网络转主机
        // 拿出客户端的ip和端口号
        char ipstr[64];
        inet_ntop(AF_INET, &peer.sin_addr, ipstr, sizeof(ipstr)); // 网络转主机
        *clientip = ipstr;                                        // 网络转主机
        *clientport = ntohs(peer.sin_port);                       // 网络转主机
        return newfd;
    }
    void Close()
    {
        close(sockfd_);
    }
    int Connect(const string &ip, const uint16_t &port) // 方便两个客户端和服务器都能使用这个Sock的这个公共方法
    {
        struct sockaddr_in peer;
        memset(&peer, 0, sizeof(peer));
        peer.sin_family = AF_INET;
        peer.sin_port = htons(port);
        inet_pton(AF_INET, ip.c_str(), &(peer.sin_addr));
        int n = connect(sockfd_, (struct sockaddr *)&peer, sizeof(peer));
        if (n == -1)
        {
            cerr << "connect to" << ip << "::" << port <<"error"<< endl;
            return false;
        }

        return true;
    }
    int Fd()
    {
        return sockfd_;
    }

private:
    int sockfd_;
};

wwwroot/a/b/hello.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" const="width=device-width,initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>第二个网页</h1>
    <h1>第二个网页</h1>
    <h1>第二个网页</h1>
    <h1>第二个网页</h1>
    <h1>第二个网页</h1>
    <h1>第二个网页</h1>
</body>
</html>

wwwroot/image

wwwroot/index.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" const="width=device-width,initial-scale=1.0">
    <title>Document</title>
</head>

<body>


    <!-- <form action="/a/b/hello.html" method="post">
        name: <input type="text" name="name"><br>
        password: <input type="password" name="password"><br>
        <input type="submit" value="提交">
    </form> -->
    <h1>这是我们的首页</h1>
    <img src="image/OIP-C.jpg" alt="这是一个咖啡">



</body>

</html>

<!-- <!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" const="width=device-width,initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>hello world</h1>
    <h1>hello world</h1>
    <h1>hello world</h1>
    <h1>hello world</h1>
    <h1>hello world</h1>
    <h1>hello world</h1>

    <a href="https://blog.csdn.net/2401_83427936?spm=1000.2115.3001.5343">Ljw的博客链接</a>
    <a href="https://101.34.66.193:8080/a/b/hello.html">第二个网页</a>
</body>
</html> -->

wwwroot/x/y/world.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" const="width=device-width,initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>第三个网页</h1>
    <h1>第三个网页</h1>
    <h1>第三个网页</h1>
    <h1>第三个网页</h1>
    <h1>第三个网页</h1>
    <h1>第三个网页</h1>
</body>
</html>

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

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

相关文章

docker服务容器化

docker服务容器化 1 引言2 多个容器间网络联通2.1 单独创建关联2.2 创建时关联 3 服务搭建3.1 镜像清单3.2 容器创建 4 联合实战4.2 flink_sql之kafka到starrocks4.2 flink_sql之mysql到starrocks 5 文献借鉴 1 引言 ​ 利用docker可以很效率地搭建服务&#xff0c;本文在win1…

Linux系统之iotop命令的基本使用

Linux系统之iotop命令的基本使用 一、iotop命令介绍二、iotop命令的使用帮助2.1 安装iotop2.2 iotop命令help帮助信息2.3 iotop命令选项解释 三、 iotop命令的基本使用四、iotop使用注意事项 一、iotop命令介绍 iotop 是一个类似于 top 的命令行工具&#xff0c;但它专注于显示…

opencv 区域提取三种算法

opencv 区域提取三种算法 1.轮廓查找 findContours()函数&#xff0c;得到轮廓的点集集合 cv::vector<cv::vector<Point>> contours;threshold(roiMat,binImg,m_pPara.m_nMinGray,m_pPara.m_nMaxGray,THRESH_BINARY);//膨胀处理Mat dilaElement getStructuringE…

【深度学习】—CNN卷积神经网络 从原理到实现

卷积神经网络&#xff08;CNN&#xff09;从原理到实现 什么是卷积神经网络&#xff08;CNN&#xff09;&#xff1f; 卷积神经网络&#xff08;Convolutional Neural Network, CNN&#xff09;是一种深度学习模型&#xff0c;主要应用于图像分类、目标检测和自然语言处理等领…

A-star算法

算法简介 A*&#xff08;A-star&#xff09;算法是一种用于图形搜索和路径规划的启发式搜索算法&#xff0c;它结合了最佳优先搜索&#xff08;Best-First Search&#xff09;和Dijkstra算法的思想&#xff0c;能够有效地寻找从起点到目标点的最短路径。A*算法广泛应用于导航、…

【数据集划分】训练集train/验证集val/测试集test是如何划分的?

&#x1f680;在跑代码时常常将数据集简单的划分为训练集train和测试集test(二划分)&#xff0c;其实更为全面完整的划分应该是划分为训练集train、验证集val、测试集test(三划分)。那么具体如何划分呢&#xff1f;各个部分起着什么作用呢&#xff1f; 如下图所示&#xff0c;…

Gentoo Linux部署LNMP

一、安装nginx 1.gentoo-chxf ~ # emerge -av nginx 提示配置文件需更新 2.gentoo-chxf ~ # etc-update 3.gentoo-chxf ~ # emerge -av nginx 4.查看并启动nginx gentoo-chxf ~ # systemctl status nginx gentoo-chxf ~ # systemctl start nginx gentoo-chxf ~ # syst…

Ubantu系统非root用户安装docker教程

非root用户没有超级权限&#xff0c;根据docker安装教程安装完毕会发现无法拉取镜像&#xff0c;或者每次运行docker都需要加上sudo&#xff0c;输入密码验证。 解决办法如下&#xff1a; 1、创建docker用户组 sudo groupadd docker2、将非root用户&#xff08;当前用户&am…

python可视化高纬度特征

可视化网络的特征层&#xff0c;假如resnet网络输出的特征维度是(batch_size,512). 如果要可视化测试集的每个图片的512高维度特征分布呢&#xff1f; embeds resnet18(x)&#xff0c;embeds是(batch_size,512)高维度特征。如下可视化。 import torch import matplotlib.pyp…

OceanBase 大数据量导入(obloader)

现需要将源数据库&#xff08;Oracle|MySQL等&#xff09;一些表的海量数据迁移到目标数据库 OceanBase 中&#xff0c;基于常规 jdbc 驱动编码的方式涉及开发工作&#xff0c;性能效率也要看编码的处理机制。 OceanBase 官方提供了的 OceanBase Migration Service (OMS) 数据…

Mac启动服务慢问题解决,InetAddress.getLocalHost().getHostAddress()慢问题。

项目启动5分钟&#xff0c;很明显有问题。像网上其他的提高jvm参数就不说了&#xff0c;应该不是这个问题&#xff0c;也就快一点。 首先找到自己的电脑名称&#xff08;用命令行也行&#xff0c;只要能找到自己电脑名称就行&#xff0c;这里直接在共享里看&#xff09;。 复制…

Ubuntu交叉编译 opencv for QNX

前言 在高通板子上开发一些程序的时候,会用到opencv帮助处理一下图像数据,高通车载板子sa8155和sm8295都有QNX os,需要交叉编译opencv的库,(这个交叉编译真是搞得我太恶心了,所以进行一个记录和分享) 搜了很多资料,有些太过于复杂,有些也存在错误导致最后没有编译成…

.NET 9 AOT的突破 - 支持老旧Win7与XP环境

引言 随着技术的不断进步&#xff0c;微软的.NET 框架在每次迭代中都带来了令人惊喜的新特性。在.NET 9 版本中&#xff0c;一个特别引人注目的亮点是 AOT&#xff08; Ahead-of-Time&#xff09;支持&#xff0c;它允许开发人员将应用程序在编译阶段就优化为能够在老旧的 Win…

Mac 环境下类Xshell 的客户端介绍

在 Mac 环境下&#xff0c;类似于 Windows 环境中 Xshell 用于访问 Linux 服务器的工具主要有以下几种&#xff1a; SecureCRT&#xff1a; 官网地址&#xff1a;https://www.vandyke.com/products/securecrt/介绍&#xff1a;支持多种协议&#xff0c;如 SSH1、SSH2、Telnet 等…

Cookie跨域

跨域&#xff1a;跨域名&#xff08;IP&#xff09; 跨域的目的是共享Cookie。 session操作http协议&#xff0c;每次既要request&#xff0c;也要response&#xff0c;cookie在创建的时候会产生一个字符串然后随着response返回。 全网站的各个页面都会带着登陆的时候的cookie …

虚拟机CentOS系统通过Docker部署RSSHub并映射到主机

公告 &#x1f4cc;更新公告 20241124-该文章已同步更新到作者的个人博客&#xff08;链接&#xff1a;虚拟机CentOS系统通过Docker部署RSSHub并映射到主机&#xff09; 一、编辑 YUM 配置文件 1、打开 CentOS 系统中的 YUM 软件仓库配置文件 vim /etc/yum.repos.d/CentOS-Ba…

DreamCamera2相机预览变形的处理

最近遇到一个问题&#xff0c;相机更换了摄像头后&#xff0c;发现人像角度顺时针旋转了90度&#xff0c;待人像角度正常后&#xff0c;发现 预览时图像有挤压变形&#xff0c;最终解决。在此记录 一人像角度的修改 先放示意图 设备预览人像角度如图1所示&#xff0c;顺时针旋…

Taro React小程序开发框架 总结

目录 一、安装 二、目录结构 三、创建一个自定义页面 四、路由 1、API 2、传参 3、获取路由参数 4、设置TabBar 五、组件 六、API Taro非常好用的小程序框架&#xff0c;React开发者无缝衔接上。 一、安装 官方文档&#xff1a;Taro 文档 注意&#xff0c;项目创建…

RPA:电商订单处理自动化

哈喽&#xff0c;大家好&#xff0c;我是若木&#xff0c;最近闲暇时间较多&#xff0c;于是便跟着教程做了一个及RPA&#xff0c;谈到这个&#xff0c;可能很多人并不是很了解&#xff0c;但是实际上&#xff0c;这玩意却遍布文末生活的边边角角。话不多说&#xff0c;我直接上…

通过金蝶云星空实现高效仓储管理

金蝶云星空数据集成到旺店通WMS的技术案例分享 在企业日常运营中&#xff0c;库存管理和物流调度是至关重要的环节。为了实现高效的数据流转和业务协同&#xff0c;我们采用了轻易云数据集成平台&#xff0c;将金蝶云星空的数据无缝对接到旺店通WMS。本次案例聚焦于“调拨入库…