完整教程:SOC-ESP32S3部分:25-HTTP请求

news/2025/10/5 17:37:49/文章来源:https://www.cnblogs.com/ljbguanli/p/19126779

完整教程:SOC-ESP32S3部分:25-HTTP请求

飞书文档https://x509p6c8to.feishu.cn/wiki/KL4RwxUQdipzCSkpB2lcBd03nvK

HTTP(Hyper Text Transfer Protocol) 超文本传输协议,是一种建立在 TCP 上的无状态连接,整个基本的工作流程是客户端发送一个 HTTP 请求,说明客户端想要访问的资源和请求的动作,服务端收到请求之后,服务端开始处理请求,并根据请求做出相应的动作访问服务器资源,最后通过发送 HTTP 响应把结果返回给客户端。

HTTP请求方法:

一般有 GET、POST、PUT、DELETE,含义分别是获取、修改、上传、删除.

其中 GET 方式仅仅为获取服务器资源,方式较为简单,因此在请求方式为 GET 的 HTTP 请求数据中,请求正文部分可以省略,直接将想要获取的资源添加到 URL 中。

请求头:包括一些访问的域名、用户代理、Cookie等信息。

请求正文:就是HTTP请求的数据。

如下发,就是一个简单的HTTP请求示例,在执行HTTP请求前,设备必须先进行配网,配网使用的是我们上节课讲解的代码。

HTTP部分核心逻辑如下,设备配网成功后,设置全局变量is_connect_wifi为true,然后执行http_get_request发送一次GET请求,请求发送给http://www.example.com/服务器。

主要流程如下:

  1. 配置http请求参数和回调处理函数
  2. 初始化http客户端
  3. 执行http请求,监听回调
  4. 清理HTTP客户端资源,释放句柄。

配置http请求参数和回调处理函数

esp_http_client_config_t描述: 配置ESP32 HTTP客户端的参数。字段:.method: HTTP请求方法,例如 HTTP_METHOD_GET 表示GET请求。.url: 请求的目标URL。.event_handler: 自定义事件处理函数,用于处理HTTP请求过程中的事件。.user_data: 用户自定义数据,可以传递给事件处理函数或存储响应数据。  _http_event_handler描述: 自定义的HTTP事件处理函数。用途: 处理HTTP请求过程中发生的事件(如连接建立、数据接收等)。注意: 代码中未提供具体实现,但通常需要根据事件类型执行相应的逻辑。 使用示例:    char local_response_buffer[MAX_HTTP_OUTPUT_BUFFER] = {0};    esp_http_client_config_t config = {        .method = HTTP_METHOD_GET,           //get请求        .url = "http://www.example.com/",     //请求url        .event_handler = _http_event_handler,        .user_data = local_response_buffer,        // Pass address of local buffer to get response    };   _http_event_handler为http请求后的回调函数:esp_err_t _http_event_handler(esp_http_client_event_t *evt){    switch(evt->event_id) {        case HTTP_EVENT_ERROR:    //错误事件            ESP_LOGI(TAG, "HTTP_EVENT_ERROR");            break;        case HTTP_EVENT_ON_CONNECTED:    //连接成功事件            ESP_LOGI(TAG, "HTTP_EVENT_ON_CONNECTED");            break;        case HTTP_EVENT_HEADER_SENT:    //发送头事件            ESP_LOGI(TAG, "HTTP_EVENT_HEADER_SENT");            break;        case HTTP_EVENT_ON_HEADER:    //接收头事件            ESP_LOGI(TAG, "HTTP_EVENT_ON_HEADER");            break;        case HTTP_EVENT_ON_DATA:    //接收数据事件            ESP_LOGI(TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len);            break;        case HTTP_EVENT_ON_FINISH:    //会话完成事件            ESP_LOGI(TAG, "HTTP_EVENT_ON_FINISH");            break;        case HTTP_EVENT_DISCONNECTED:    //断开事件            ESP_LOGI(TAG, "HTTP_EVENT_DISCONNECTED");            break;        case HTTP_EVENT_REDIRECT:            break;    }    return ESP_OK;}

初始化http客户端

esp_http_client_initesp_http_client_handle_t esp_http_client_init(const esp_http_client_config_t *config);功能: 初始化HTTP客户端并返回句柄。参数:config: 指向esp_http_client_config_t结构体的指针,包含HTTP客户端的配置信息。返回值: 返回HTTP客户端的句柄。

执行http请求

esp_err_t esp_http_client_perform(esp_http_client_handle_t client);功能: 执行HTTP请求并等待响应。参数:client: HTTP客户端句柄。返回值:ESP_OK: 请求成功。其他错误码: 请求失败。

清理HTTP客户端资源,释放句柄。

void esp_http_client_cleanup(esp_http_client_handle_t client);功能: 清理HTTP客户端资源,释放句柄。参数:client: HTTP客户端句柄。

最终代码如下:

#include #include #include "freertos/FreeRTOS.h"#include "freertos/task.h"#include "freertos/event_groups.h"#include "esp_eap_client.h"#include "esp_netif.h"#include "esp_smartconfig.h"#include "esp_mac.h"#include "esp_system.h"#include "esp_wifi.h"#include "esp_event.h"#include "esp_log.h"#include "nvs_flash.h" #include "esp_http_client.h" static const char *TAG = "http_client"; static EventGroupHandle_t s_wifi_event_group; static const int CONNECTED_BIT = BIT0;static const int ESPTOUCH_DONE_BIT = BIT1;static void smartconfig_example_task(void *parm);static bool is_connect_wifi = false; #define MAX_HTTP_OUTPUT_BUFFER 2048 esp_err_t _http_event_handler(esp_http_client_event_t *evt){    switch(evt->event_id) {        case HTTP_EVENT_ERROR:    //错误事件            ESP_LOGI(TAG, "HTTP_EVENT_ERROR");            break;        case HTTP_EVENT_ON_CONNECTED:    //连接成功事件            ESP_LOGI(TAG, "HTTP_EVENT_ON_CONNECTED");            break;        case HTTP_EVENT_HEADER_SENT:    //发送头事件            ESP_LOGI(TAG, "HTTP_EVENT_HEADER_SENT");            break;        case HTTP_EVENT_ON_HEADER:    //接收头事件            ESP_LOGI(TAG, "HTTP_EVENT_ON_HEADER");            printf("%.*s", evt->data_len, (char*)evt->data);            break;        case HTTP_EVENT_ON_DATA:    //接收数据事件            ESP_LOGI(TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len);            if (!esp_http_client_is_chunked_response(evt->client)) {                printf("%.*s", evt->data_len, (char*)evt->data);            }            break;        case HTTP_EVENT_ON_FINISH:    //会话完成事件            ESP_LOGI(TAG, "HTTP_EVENT_ON_FINISH");            break;        case HTTP_EVENT_DISCONNECTED:    //断开事件            ESP_LOGI(TAG, "HTTP_EVENT_DISCONNECTED");            break;        case HTTP_EVENT_REDIRECT:            break;    }    return ESP_OK;} static void http_get_request(){    char local_response_buffer[MAX_HTTP_OUTPUT_BUFFER] = {0};    esp_http_client_config_t config = {        .method = HTTP_METHOD_GET,           //get请求        .url = "http://www.example.com/",     //请求url        .event_handler = _http_event_handler,        .user_data = local_response_buffer,        // Pass address of local buffer to get response    };    esp_http_client_handle_t client = esp_http_client_init(&config);    // GET    esp_err_t err = esp_http_client_perform(client);    if (err == ESP_OK) {        ESP_LOGI(TAG, "HTTP GET OK");    } else {        ESP_LOGE(TAG, "HTTP GET request failed: %s", esp_err_to_name(err));    }    ESP_LOGI(TAG, "%s\n", local_response_buffer);       esp_http_client_cleanup(client);} static void http_get_task(void *pvParameters){    while (1)    {        if (is_connect_wifi)        {            http_get_request();        }        vTaskDelay(8000 / portTICK_PERIOD_MS);    }} static void event_handler(void *arg, esp_event_base_t event_base,                          int32_t event_id, void *event_data){    if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START)    {        // WiFi 站点模式启动后,创建 SmartConfig 任务        xTaskCreate(smartconfig_example_task, "smartconfig_example_task", 4096, NULL, 3, NULL);    }    else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED)    {        is_connect_wifi = false;        // WiFi 断开连接时,重新连接并清除连接标志位        esp_wifi_connect();        xEventGroupClearBits(s_wifi_event_group, CONNECTED_BIT);    }    else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP)    {        // 获取到 IP 地址后,设置连接标志位        xEventGroupSetBits(s_wifi_event_group, CONNECTED_BIT);        is_connect_wifi = true;    }    else if (event_base == SC_EVENT && event_id == SC_EVENT_SCAN_DONE)    {        // SmartConfig 扫描完成事件        ESP_LOGI(TAG, "Scan done");    }    else if (event_base == SC_EVENT && event_id == SC_EVENT_FOUND_CHANNEL)    {        // SmartConfig 找到信道事件        ESP_LOGI(TAG, "Found channel");    }    else if (event_base == SC_EVENT && event_id == SC_EVENT_GOT_SSID_PSWD)    {        // SmartConfig 获取到 SSID 和密码事件        ESP_LOGI(TAG, "Got SSID and password");        smartconfig_event_got_ssid_pswd_t *evt = (smartconfig_event_got_ssid_pswd_t *)event_data;        wifi_config_t wifi_config;        uint8_t ssid[33] = {0};        uint8_t password[65] = {0};        uint8_t rvd_data[33] = {0};         bzero(&wifi_config, sizeof(wifi_config_t));        memcpy(wifi_config.sta.ssid, evt->ssid, sizeof(wifi_config.sta.ssid));        memcpy(wifi_config.sta.password, evt->password, sizeof(wifi_config.sta.password));         memcpy(ssid, evt->ssid, sizeof(evt->ssid));        memcpy(password, evt->password, sizeof(evt->password));        ESP_LOGI(TAG, "SSID:%s", ssid);        ESP_LOGI(TAG, "PASSWORD:%s", password);        if (evt->type == SC_TYPE_ESPTOUCH_V2)        {            // 如果使用的是 ESPTouch V2,获取额外的数据            ESP_ERROR_CHECK(esp_smartconfig_get_rvd_data(rvd_data, sizeof(rvd_data)));            ESP_LOGI(TAG, "RVD_DATA:");            for (int i = 0; i  0)    {        // 如果配置过,就直接连接wifi        ESP_LOGI(TAG, "alrealy set, SSID is :%s,start connect", myconfig.sta.ssid);        esp_wifi_connect();    }    else    {        // 如果没有配置过,就进行配网操作        ESP_LOGI(TAG, "have no set, start to config");        ESP_ERROR_CHECK(esp_smartconfig_set_type(SC_TYPE_ESPTOUCH_AIRKISS)); // 支持APP ESPTOUCH和微信AIRKISS        smartconfig_start_config_t cfg = SMARTCONFIG_START_CONFIG_DEFAULT();        ESP_ERROR_CHECK(esp_smartconfig_start(&cfg));    }    while (1)    {        // 等待连接标志位或 SmartConfig 完成标志位        uxBits = xEventGroupWaitBits(s_wifi_event_group, CONNECTED_BIT | ESPTOUCH_DONE_BIT, true, false, portMAX_DELAY);        if (uxBits & CONNECTED_BIT)        {            // 连接到 AP 后的日志            ESP_LOGI(TAG, "WiFi Connected to ap");            // 联网成功后,可以关闭线程            vTaskDelete(NULL);        }        if (uxBits & ESPTOUCH_DONE_BIT)        {            // SmartConfig 完成后的日志            ESP_LOGI(TAG, "smartconfig over");            // 停止 SmartConfig            esp_smartconfig_stop();            // 删除 SmartConfig 任务            vTaskDelete(NULL);        }    }} void app_main(void){    // 初始化 NVS 闪存    ESP_ERROR_CHECK( nvs_flash_init());    // 初始化网络接口    ESP_ERROR_CHECK(esp_netif_init());    // 创建事件组    s_wifi_event_group = xEventGroupCreate();    // 创建默认事件循环    ESP_ERROR_CHECK(esp_event_loop_create_default());    // 创建默认的 WiFi 站点模式网络接口    esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();    assert(sta_netif);     // 初始化 WiFi 配置    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();    ESP_ERROR_CHECK(esp_wifi_init(&cfg));     // 注册事件处理函数    ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));    ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL));    ESP_ERROR_CHECK(esp_event_handler_register(SC_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));     // 设置 WiFi 模式为站点模式并启动 WiFi    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));    ESP_ERROR_CHECK(esp_wifi_start());     xTaskCreate(&http_get_task, "http_get_task", 9192, NULL, 5, NULL);}

对于POST请求

只需要把esp_http_client_config_t的method设置为HTTP_METHOD_POST,另外安装服务器的参数,填写esp_http_client_set_header和esp_http_client_set_post_field即可。例如,我们需要发送JSON数据包{"field1":"value1"}给服务器http://httpbin.org/post,具体POST请求实现如下:

static void http_post(void){    esp_http_client_config_t config = {        .method = HTTP_METHOD_POST,                .url = "http://httpbin.org/post",            .event_handler = _http_event_handler,    };    esp_http_client_handle_t client = esp_http_client_init(&config);    // POST    const char *post_data = "{\"field1\":\"value1\"}";    esp_http_client_set_header(client, "Content-Type", "application/json");    esp_http_client_set_post_field(client, post_data, strlen(post_data));    esp_err_t err = esp_http_client_perform(client);    if (err == ESP_OK) {        ESP_LOGI(TAG, "HTTP POST OK");    } else {        ESP_LOGE(TAG, "HTTP POST request failed: %s", esp_err_to_name(err));    }    esp_http_client_cleanup(client);}

对于HTTPS请求

只需额外配置esp_http_client_config_t 的url为https连接,另外添加证书文件即可cert_pem,例如

esp_http_client_config_t config = {        .method = HTTP_METHOD_GET,        .url = "https://www.howsmyssl.com/",        .event_handler = _http_event_handler,        .cert_pem = howsmyssl_com_root_cert_pem_start,    };

esp_http_client_config_t更多参数说明如下:可按需使用

typedef struct {    const char                  *url;    /*!< HTTP URL,URL 信息是最重要的,如果设置了此参数,它将覆盖下面的其他字段(如果有的话) */    const char                  *host;    /*!< 以字符串形式表示的域名或 IP 地址 */    int                         port;    /*!< 要连接的端口,默认值取决于 esp_http_client_transport_t(80 用于 HTTP,443 用于 HTTPS) */    const char                  *username;    /*!< 用于 HTTP 认证 */    const char                  *password;    /*!< 用于 HTTP 认证 */    esp_http_client_auth_type_t auth_type;    /*!< HTTP 认证类型,请参阅 `esp_http_client_auth_type_t` */    const char                  *path;    /*!< HTTP 路径,如果未设置,默认值为 `/` */    const char                  *query;    /*!< HTTP 查询字符串 */    const char                  *cert_pem;    /*!< SSL 服务器证书,以 PEM 格式表示的字符串,如果客户端需要验证服务器 */    size_t                      cert_len;    /*!< 指向 cert_pem 的缓冲区长度。如果是 null 结尾的 PEM 字符串,可为 0 */    const char                  *client_cert_pem;    /*!< SSL 客户端证书,以 PEM 格式表示的字符串,如果服务器需要验证客户端 */    size_t                      client_cert_len;    /*!< 指向 client_cert_pem 的缓冲区长度。如果是 null 结尾的 PEM 字符串,可为 0 */    const char                  *client_key_pem;    /*!< SSL 客户端密钥,以 PEM 格式表示的字符串,如果服务器需要验证客户端 */    size_t                      client_key_len;    /*!< 指向 client_key_pem 的缓冲区长度。如果是 null 结尾的 PEM 字符串,可为 0 */    const char                  *client_key_password;    /*!< 客户端密钥解密密码字符串 */    size_t                      client_key_password_len;    /*!< 指向 client_key_password 的密码字符串长度 */    esp_http_client_proto_ver_t tls_version;    /*!< 连接的 TLS 协议版本,例如,TLS 1.2、TLS 1.3(默认 - 无偏好) */#ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN    bool                        use_ecdsa_peripheral;    /*!< 使用 ECDSA 外设来使用私钥 */    uint8_t                     ecdsa_key_efuse_blk;    /*!< ECDSA 密钥存储的 efuse 块 */#endif    const char                  *user_agent;    /*!< 随 HTTP 请求发送的用户代理字符串 */    esp_http_client_method_t    method;    /*!< HTTP 请求方法 */    int                         timeout_ms;    /*!< 网络超时时间,单位为毫秒 */    bool                        disable_auto_redirect;    /*!< 禁用 HTTP 自动重定向 */    int                         max_redirection_count;    /*!< 收到 HTTP 重定向状态码时的最大重定向次数,如果为 0,则使用默认值 */    int                         max_authorization_retries;    /*!< 收到 HTTP 未授权状态码时的最大连接重试次数,如果为 0,则使用默认值。如果为 -1,则禁用授权重试 */    http_event_handle_cb        event_handler;    /*!< HTTP 事件处理函数 */    esp_http_client_transport_t transport_type;    /*!< HTTP 传输类型,请参阅 `esp_http_client_transport_t` */    int                         buffer_size;    /*!< HTTP 接收缓冲区大小 */    int                         buffer_size_tx;    /*!< HTTP 发送缓冲区大小 */    void                        *user_data;    /*!< HTTP 用户数据上下文 */    bool                        is_async;    /*!< 设置异步模式,目前仅支持 HTTPS */    bool                        use_global_ca_store;    /*!< 对所有设置了此布尔值的连接使用全局 CA 证书存储 */    bool                        skip_cert_common_name_check;    /*!< 跳过对服务器证书 CN 字段的任何验证 */    const char                  *common_name;    /*!< 指向包含服务器证书通用名称的字符串指针。         如果不为 NULL,服务器证书的 CN 必须与此名称匹配;         如果为 NULL,服务器证书的 CN 必须与主机名匹配。 */    esp_err_t (*crt_bundle_attach)(void *conf);    /*!< 指向 esp_crt_bundle_attach 的函数指针。启用使用证书包进行服务器验证,必须在菜单配置中启用 */    bool                        keep_alive_enable;    /*!< 启用 keep-alive 超时机制 */    int                         keep_alive_idle;    /*!< keep-alive 空闲时间。默认值为 5(秒) */    int                         keep_alive_interval;    /*!< keep-alive 间隔时间。默认值为 5(秒) */    int                         keep_alive_count;    /*!< keep-alive 数据包重试发送次数。默认值为 3 次 */    struct ifreq                *if_name;    /*!< 数据要通过的接口名称。如果未设置,则使用默认接口 */#if CONFIG_ESP_TLS_USE_SECURE_ELEMENT    bool use_secure_element;    /*!< 启用此选项以使用安全元件 */#endif#if CONFIG_ESP_TLS_USE_DS_PERIPHERAL    void *ds_data;    /*!< 数字签名外设上下文指针,更多详细信息请参阅 ESP - TLS 文档 */#endif#if CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS    bool save_client_session;#endif#if CONFIG_ESP_HTTP_CLIENT_ENABLE_CUSTOM_TRANSPORT    struct esp_transport_item_t *transport;#endif} esp_http_client_config_t;

HTTPS请求需要做服务器证书校验,所以需要添加证书,证书是由服务器提供的,这里用到两个服务器进行测试,所以需要用到两个证书,拷贝idf证书到工程main下方

esp-idf/examples/protocols/esp_http_client/main/howsmyssl_com_root_cert.pem

esp-idf/examples/protocols/esp_http_client/main/postman_root_cert.pem

拷贝证书到工程路径后,还需要添加到CMakeLists.txt中,保证烧录到设备中

demo/main/CMakeLists.txt

idf_component_register(                    SRCS "main.c"                    INCLUDE_DIRS "."                    EMBED_TXTFILES howsmyssl_com_root_cert.pem postman_root_cert.pem                    )

最后请求代码如下:

//howsmyssl服务器证书位置extern const char howsmyssl_com_root_cert_pem_start[] asm("_binary_howsmyssl_com_root_cert_pem_start");extern const char howsmyssl_com_root_cert_pem_end[]   asm("_binary_howsmyssl_com_root_cert_pem_end");//postman服务器证书位置extern const char postman_root_cert_pem_start[] asm("_binary_postman_root_cert_pem_start");extern const char postman_root_cert_pem_end[]   asm("_binary_postman_root_cert_pem_end");  static void https_get_request(void){    esp_http_client_config_t config = {        .method = HTTP_METHOD_GET,        .url = "https://www.howsmyssl.com/",        .event_handler = _http_event_handler,        .cert_pem = howsmyssl_com_root_cert_pem_start,    };    esp_http_client_handle_t client = esp_http_client_init(&config);    esp_err_t err = esp_http_client_perform(client);     if (err == ESP_OK) {        ESP_LOGI(TAG, "HTTPS Status = %d, content_length = %"PRId64,                esp_http_client_get_status_code(client),                esp_http_client_get_content_length(client));    } else {        ESP_LOGE(TAG, "Error perform http request %s", esp_err_to_name(err));    }    esp_http_client_cleanup(client);} static void https_post(){    esp_http_client_config_t config = {        .method = HTTP_METHOD_POST,        .url = "https://www.postman-echo.com/post",        .event_handler = _http_event_handler,        .cert_pem = postman_root_cert_pem_start,        .is_async = true,        .timeout_ms = 5000,    };    esp_http_client_handle_t client = esp_http_client_init(&config);    esp_err_t err;    const char *post_data = "this is xiaozhi post data";    esp_http_client_set_post_field(client, post_data, strlen(post_data));    while (1) {        err = esp_http_client_perform(client);        if (err != ESP_ERR_HTTP_EAGAIN) {            break;        }    }    if (err == ESP_OK) {        ESP_LOGI(TAG, "HTTPS Status = %d, content_length = %"PRId64,                esp_http_client_get_status_code(client),                esp_http_client_get_content_length(client));    } else {        ESP_LOGE(TAG, "Error perform http request %s", esp_err_to_name(err));    }    esp_http_client_cleanup(client);}

这个实验需要先完成WiFi配网哦,具体看WiFi章节24-WiFi配网

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

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

相关文章

为什么要采用“接口 - 抽象类 - 实现类”这种三层结构? - 浪矢

目录核心思想各层职责与优势第一层:接口 (Interface) - 负责“定义契约”,实现“解耦”第二层:抽象类 (Abstract Class) - 负责“封装通用”,实现“复用”第三层:实现类 (Implementation Class) - 负责“具体业务…

对外提供 AI 服务的风险:合规视角与 AI 安全围栏落地指南

对外提供人工智能服务,主要风险集中在提示词攻击与越权操控、不当内容输出与内容合规、敏感信息与个人信息泄露,以及算法合规、备案与可审计义务。自2023年《生成式人工智能服务管理暂行办法》实施后,企业需要把“数…

遵义市做网站设计公司苏州关键词优化排名推广

本文转载自&#xff1a;http://blog.sina.com.cn/s/blog_9a06890901014ol1.html PHP页面跳转一、header()函数 header函数中Location类型的标头是一种特殊的header调用&#xff0c;常用来实现页面跳转 注意&#xff1a;1、location和“:”号间不能有空格&#xff0c;否则不会跳…

网络安全工具与社区讨论月报

本文记录了r/netsec网络安全社区月度讨论帖,包含成员分享的常用安全工具如Burp Suite和Nuclei,以及社区规则和最新动态,为安全从业者提供实用参考。r/netsec 月度讨论与工具分享帖 社区介绍 /r/netsec 是一个由社区…

机器人运动未来与人机交互研究

本文探讨了机器人运动与人机长期交互的前沿研究,包括机器人意图信号系统、机器学习在机器人感知中的应用,以及大规模实验环境对机器人技术发展的重要性。机器人运动未来与人机交互研究 移动机器人正日益普及:它们在…

欧拉路径 欧拉图 小记

欧拉路径 & 欧拉图 小记 P7771 【模板】欧拉路径 欧拉路径:一个图中经过每条边恰好一次的路径,允许经过重复点。 欧拉回路:起点与终点相同的欧拉路径。 对于连通图,欧拉路径有如下判定:对于无向图,恰好有两个…

OI 笑传 #16

The Taste of Kindness指差す先はインナーワールド 1 ABC423F 终于会了不用二项式反演的做法。 我们把这种东西叫什么好呢?预处理容斥系数? 首先这题是不能一般容斥的,因为我们求解的不是并集,而是独立集。 哎哎独…

课后知识整理

课后知识整理Java方法动手动脑与实验问题全记录 静态导入实验 实验:随机数 Math.random() 局限性 (int)(Math.random()*6) 只能生成 0–5,而不能公平生成 1–6。 Random 带种子实验 实验:

cf296b

CF296B Yaroslav and Two Strings link 题意 给定两个由数字和 ? 组成的字符串 \(s,t\),将 ? 替换为数字。若 \(s,t\) 中有 \(s_i>w_i,s_j<w_j(1\leq i,j\leq n)\),则是一种合法的替换。求合法的方案数对 \(…

昆山做网站费用个人工作室怎么注册

这个教程会教您如何设计发光斑驳的字体特效&#xff0c;会教您运用PS滤镜和纹理图片&#xff0c;同时也诠释了如何运用笔刷和图层样式给最终的字体效果增添光感。来&#xff0c;先看看最终效果&#xff01;第一步&#xff1a;创建一个1024*768的新文档。前景色#532118&#xff…

云原生与DevOps融合实践:加速企业数字化转型的加速器 - 详解

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

第一次使用Ttpora

MarkDown使用教学 两个井号创建二级标题 一个井号创建一级标题就是最上边的那个 字体 两边都加星号,字体就变成黑色了 两边都加星号,字体就变成黑色了 两边都加两个星号,字体就变成黑色了 两边加一个型号,变成斜体…

Apache反向代理

“apache2 网站静态文件” = /var/www/html/ Apache 本身就可以作为一个反向代理服务器来使用,通常是通过 mod_proxy 及其附加模块来实现。 下面是启用 Apache 反向代理的基本步骤: 1. 启用必要的模块 你需要启用以下…

原版 Sunshine+虚拟显示器实现熄屏串流

Sunshine 基地版 是一个很好的软件,自带了虚拟显示器,能够非常方便地实现熄屏串流,但有一个 bug,它会在串流结束后自动开启虚拟显示器的 HDR 功能:https://github.com/qiin2333/Sunshine-Foundation/issues/13 很…

一流的嘉兴网站建设最牛的视频网站建设

目录 第一章&#xff1a;Java Web基础知识1.介绍3.Java Web基本概念 4.常见面试问题第二章&#xff1a;Java Web核心概念和技术1.介绍3.Servlet和JSP4.Web安全5.常见面试问题 第三章&#xff1a;Java Web高级概念和技术1.介绍3.Spring框架4.安全性5.常见面试问题 第四章&#x…

2025国庆Day4

模拟赛 T1 简单做法: 发现本题所有运算全是加法 直接记录c,s之和 转移即可 #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<…

苏宁易购网站建设目标成视频网址多少?

场景&#xff1a; 平台&#xff1a;win7 x64。显卡很差的电脑&#xff0c;使用ffmpeg录屏&#xff0c;鼠标闪烁的几乎看不到。录屏实现方法是使用ffmpeg&#xff0c;源采用的是gdigrab。 解决方法&#xff1a; 安装screen capture recorder安装ffmpeg&#xff0c;执行命令ff…

郑州网站开发公司电话网站在线优化

简介&#xff1a; 融合流量网关与微服务网关的下一代网关—云原生网关来啦&#xff01;优势满满&#xff01; 流量网关和微服务网关必须分开构建吗&#xff1f; 在容器技术和 K8s 主导的云原生时代&#xff0c;这个命题正浮现出新的答案。 更经济&#xff1a;将流量网关与微…

gis坐标计算

package cn.service.hspd.utils;import com.alibaba.fastjson2.JSON;import java.awt.geom.Point2D; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import ja…

Spring AI Alibaba + Nacos 动态 MCP Server 代理方案 - 详解

Spring AI Alibaba + Nacos 动态 MCP Server 代理方案 - 详解2025-10-05 16:58 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !import…