ESP32-IDF http请求崩溃问题解决

news2024/11/14 19:21:06

文章目录

  • esp32s3 http请求崩溃
  • 问题代码讨论
  • 修正后不崩溃的代码

ESP32S3板子, 一运行http请求百度网站的例子, 就会panic死机, 记录下过程.

esp32s3 http请求崩溃

一执行http请求的perform就会崩溃,
打印如图
在这里插入图片描述
ESP32-IDF 的http请求代码是根据官方demo来改的, 第一步先连接wifi, 连接上后执行http get请求百度网站. 理论上写法是没问题的,但是运行到板子上发现很容易崩溃.

问题代码讨论

会在可能有问题的地方注释,有4个问题点,具体看代码 , 最主要问题是运行内存有限, 容易发生栈或堆溢出或越界导致崩溃.

#include <stdio.h>
#include <pthread.h>

#include <string.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_err.h"
#include "esp_log.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "esp_event.h"
#include "esp_netif.h"
#include "esp_wifi.h"
#include "esp_tls.h"
#include "esp_crt_bundle.h"
#include "esp_http_client.h"


static const char *TAG = "HTTP_REQUEST";

// 这里的buffer要适当, 如果改太大了, 比如10240就可能导致死机, 要根据实际运行结果做调整
#define MAX_HTTP_OUTPUT_BUFFER 2048
#define HTTP_URL "http://www.baidu.com"

// HTTP 请求的处理函数
esp_err_t http_event_handler(esp_http_client_event_t *evt)
{
    // 缓存http响应的buffer
    static char *output_buffer;
    // 已经读取的字节数
    static int output_len;
    switch(evt->event_id) {
        case HTTP_EVENT_ERROR:
            ESP_LOGD(TAG, "HTTP_EVENT_ERROR");
            break;
        case HTTP_EVENT_ON_CONNECTED:
            ESP_LOGD(TAG, "HTTP_EVENT_ON_CONNECTED");
            break;
        case HTTP_EVENT_HEADER_SENT:
            ESP_LOGD(TAG, "HTTP_EVENT_HEADER_SENT");
            break;
        case HTTP_EVENT_ON_HEADER:
            ESP_LOGD(TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value);
            break;
        case HTTP_EVENT_ON_DATA:
            ESP_LOGD(TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len);

            if (!esp_http_client_is_chunked_response(evt->client)) {
                if (evt->user_data) {
                    // 问题1: 这里没有做防溢出限制, 当http返回的数据长度趤过预留的buffer大小MAX_HTTP_OUTPUT_BUFFER时就会溢出崩溃
                    memcpy(evt->user_data + output_len, evt->data, evt->data_len);
                } else {
                    if (output_buffer == NULL) {
                        // 问题2: 这里直接用malloc申请http返回的数据长度的堆空间, 实测在esp32s3板子上跑会崩溃
                        output_buffer = (char *) malloc(esp_http_client_get_content_length(evt->client));
                        output_len = 0;
                        if (output_buffer == NULL) {
                            ESP_LOGE(TAG, "Failed to allocate memory for output buffer");
                            return ESP_FAIL;
                        }
                    }
                    memcpy(output_buffer + output_len, evt->data, evt->data_len);
                }
                output_len += evt->data_len;
            }

            break;
        case HTTP_EVENT_ON_FINISH:
            ESP_LOGD(TAG, "HTTP_EVENT_ON_FINISH");
            if (output_buffer != NULL) {
                // Response is accumulated in output_buffer. Uncomment the below line to print the accumulated response
                // ESP_LOG_BUFFER_HEX(TAG, output_buffer, output_len);
                free(output_buffer);
                output_buffer = NULL;
            }
            output_len = 0;
            break;
        case HTTP_EVENT_DISCONNECTED:
            ESP_LOGI(TAG, "HTTP_EVENT_DISCONNECTED");
            if (output_buffer != NULL) {
                free(output_buffer);
                output_buffer = NULL;
            }
            output_len = 0;
            break;
    }
    return ESP_OK;
}

void request(const char *url) {
    printf("request  -----------1\n");
    // 响应结果放在这里
    char local_response_buffer[MAX_HTTP_OUTPUT_BUFFER] = {0};

    // 创建一个 HTTP 客户端配置
    esp_http_client_config_t config = {
            .method = HTTP_METHOD_GET,
            .url = url,
            .event_handler = http_event_handler,
            .user_data = local_response_buffer,
            .disable_auto_redirect = true,
    };

    // 创建一个 HTTP 客户端并执行 GET 请求
    esp_http_client_handle_t client = esp_http_client_init(&config);
    printf("request  -----------2\n");
    esp_err_t err = esp_http_client_perform(client); // 请求百度网页时,一执行这行系统就会崩溃
    printf("request  -----------3\n");

    // 检查请求是否成功
    if (err == ESP_OK) {
        int len =  esp_http_client_get_content_length(client);
        ESP_LOGI(TAG, "Status = %d, content_length = %d",
                 esp_http_client_get_status_code(client),//状态码
                 len);//数据长度

    } else {
        printf("HTTP GET request failed: %s\n", esp_err_to_name(err));
    }
    printf("Response: %.*s\n", strlen(local_response_buffer), local_response_buffer);

    //断开并释放资源
    esp_http_client_cleanup(client);
    printf("request  -----------4\n");
}

void http_test_task(void *arg)
{
    sleep(15);
    request(HTTP_URL);

    vTaskDelete(NULL);
}

/**
 * @brief WiFi 的事件循环Handler
 * @param arg
 * @param event_base
 * @param event_id
 * @param event_data
 */
void wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
{
    printf("wifi_event_handler base:%s, id:%d\n", event_base, event_id);
    if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START)
    {
        printf("esp_wifi_connect\n");
        esp_wifi_connect();
    }
    else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED)
    {
        printf("esp_wifi_connect\n");
        esp_wifi_connect();
    }

    if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP)
    {
        ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
        ESP_LOGI("ESP32", "IP地址:: " IPSTR, IP2STR(&event->ip_info.ip));

        //request(HTTP_URL); 问题点3: 获取到ip地址后,不要直接在这里执行http请求, 否则会直接崩溃
    }
}

void app_main(void)
{
    esp_err_t ret = nvs_flash_init(); // 初始化默认NVS分区
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
    {
        ESP_ERROR_CHECK(nvs_flash_erase()); // 擦除默认NVS分区
        ret = nvs_flash_init();             // 初始化默认NVS分区
    }
    ESP_ERROR_CHECK(ret);
    ESP_ERROR_CHECK(esp_netif_init());                // 初始化底层TCP/IP堆栈
    ESP_ERROR_CHECK(esp_event_loop_create_default()); // 创建默认事件循环

    esp_netif_create_default_wifi_sta(); // 创建默认的WIFI STA。

    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    esp_wifi_init(&cfg); // 初始化WiFi为WiFi驱动程序
    wifi_sta_config_t cfg_sta = {
        .ssid = "black",
        .password = "black1234",
        .threshold.authmode = WIFI_AUTH_WPA2_PSK,   //加密方式
        .pmf_cfg = {
            .capable = true,
            .required = false
        },
    };
    esp_wifi_set_config(WIFI_IF_STA, (wifi_config_t *)&cfg_sta); // 设置ESP32 STA或AP的配置

    esp_wifi_set_mode(WIFI_MODE_STA); // 设置WiFi操作模式

    // 将事件处理程序的实例注册到默认循环中           任何事件
    esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, wifi_event_handler, NULL, NULL);
    // 将事件处理程序的实例注册到默认循环中            工作站从连接的AP获得IP事件
    esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, wifi_event_handler, NULL, NULL);

    esp_wifi_start(); // 根据当前配置启动wifi

    xTaskCreate(&http_test_task, "http_test_task", 8192, NULL, 5, NULL); //问题点4: 这里参数需要设置足够大的栈大小, 否则会导致崩溃
}

修正后不崩溃的代码

百度网页返回的http结果太多了,会导致空间不够,
针对问题代码, 做出调整, 对栈空间大小做限制, 当http返回内容过长时,直接丢弃

#include <stdio.h>
#include <pthread.h>

#include <string.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_err.h"
#include "esp_log.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "esp_event.h"
#include "esp_netif.h"
#include "esp_wifi.h"
#include "esp_tls.h"
#include "esp_crt_bundle.h"
#include "esp_http_client.h"


static const char *TAG = "HTTP_REQUEST";
#define MAX_HTTP_OUTPUT_BUFFER 2048
#define HTTP_URL "http://www.baidu.com"

// HTTP 请求的处理函数
esp_err_t http_event_handler(esp_http_client_event_t *evt)
{
    // 缓存http响应的buffer
    static char *output_buffer;
    // 已经读取的字节数
    static int output_len;
    switch(evt->event_id) {
        case HTTP_EVENT_ERROR:
            ESP_LOGD(TAG, "HTTP_EVENT_ERROR");
            break;
        case HTTP_EVENT_ON_CONNECTED:
            ESP_LOGD(TAG, "HTTP_EVENT_ON_CONNECTED");
            break;
        case HTTP_EVENT_HEADER_SENT:
            ESP_LOGD(TAG, "HTTP_EVENT_HEADER_SENT");
            break;
        case HTTP_EVENT_ON_HEADER:
            ESP_LOGD(TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value);
            break;
        case HTTP_EVENT_ON_DATA:
            ESP_LOGD(TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len);

            if (!esp_http_client_is_chunked_response(evt->client)) {
                if (evt->user_data) {
                    // 这里对buffer长度进行判断, 如果http返回长度过长, 为防止溢出就丢弃,否则进行追加拷贝
                    int left = MAX_HTTP_OUTPUT_BUFFER - output_len -1;
                    if (left > evt->data_len)
                        memcpy(evt->user_data + output_len, evt->data, evt->data_len);
                    else if (left > 0)
                        memcpy(evt->user_data + output_len, evt->data, left);
                    else
                        ESP_LOGI(TAG, "HTTP_EVENT_ON_DATA, buffer full");
                } else {
                    // 如果实测user_data设置为空时,走这里申请堆内存会崩溃则可以注释掉这段,否则可以使用
                    if (output_buffer == NULL) {
                        output_buffer = (char *) malloc(esp_http_client_get_content_length(evt->client));
                        output_len = 0;
                        if (output_buffer == NULL) {
                            ESP_LOGE(TAG, "Failed to allocate memory for output buffer");
                            return ESP_FAIL;
                        }
                    }
                    memcpy(output_buffer + output_len, evt->data, evt->data_len);
                }
                output_len += evt->data_len;
            }

            break;
        case HTTP_EVENT_ON_FINISH:
            ESP_LOGD(TAG, "HTTP_EVENT_ON_FINISH");
            if (output_buffer != NULL) {
                // Response is accumulated in output_buffer. Uncomment the below line to print the accumulated response
                // ESP_LOG_BUFFER_HEX(TAG, output_buffer, output_len);
                free(output_buffer);
                output_buffer = NULL;
            }
            output_len = 0;
            break;
        case HTTP_EVENT_DISCONNECTED:
            ESP_LOGI(TAG, "HTTP_EVENT_DISCONNECTED");
            if (output_buffer != NULL) {
                free(output_buffer);
                output_buffer = NULL;
            }
            output_len = 0;
            break;
    }
    return ESP_OK;
}

void request(const char *url) {
    printf("request  -----------1\n");
    // 响应结果放在这里
    char local_response_buffer[MAX_HTTP_OUTPUT_BUFFER] = {0};

    // 创建一个 HTTP 客户端配置
    esp_http_client_config_t config = {
            .method = HTTP_METHOD_GET,
            .url = url,
            .event_handler = http_event_handler,
            .user_data = local_response_buffer,
            .disable_auto_redirect = true,
    };

    // 创建一个 HTTP 客户端并执行 GET 请求
    esp_http_client_handle_t client = esp_http_client_init(&config);
    printf("request  -----------2\n");
    esp_err_t err = esp_http_client_perform(client); // 请求百度网页时,一执行这行系统就会崩溃
    printf("request  -----------3\n");

    // 检查请求是否成功
    if (err == ESP_OK) {
        int len =  esp_http_client_get_content_length(client);
        ESP_LOGI(TAG, "Status = %d, content_length = %d",
                 esp_http_client_get_status_code(client),//状态码
                 len);//数据长度

    } else {
        printf("HTTP GET request failed: %s\n", esp_err_to_name(err));
    }
    printf("Response: %.*s\n", strlen(local_response_buffer), local_response_buffer);

    //断开并释放资源
    esp_http_client_cleanup(client);
    printf("request  -----------4\n");
}

void http_test_task(void *arg)
{
    sleep(15);
    request(HTTP_URL);

    vTaskDelete(NULL);
}

/**
 * @brief WiFi 的事件循环Handler
 * @param arg
 * @param event_base
 * @param event_id
 * @param event_data
 */
void wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
{
    printf("wifi_event_handler base:%s, id:%d\n", event_base, event_id);
    if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START)
    {
        printf("esp_wifi_connect\n");
        esp_wifi_connect();
    }
    else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED)
    {
        printf("esp_wifi_connect\n");
        esp_wifi_connect();
    }

    if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP)
    {
        ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
        ESP_LOGI("ESP32", "IP地址:: " IPSTR, IP2STR(&event->ip_info.ip));

        //request(HTTP_URL); 问题点2: 获取到ip地址后,不要直接在这里执行http请求, 否则会直接崩溃 , 这里注释掉不用
    }
}

void app_main(void)
{
    esp_err_t ret = nvs_flash_init(); // 初始化默认NVS分区
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
    {
        ESP_ERROR_CHECK(nvs_flash_erase()); // 擦除默认NVS分区
        ret = nvs_flash_init();             // 初始化默认NVS分区
    }
    ESP_ERROR_CHECK(ret);
    ESP_ERROR_CHECK(esp_netif_init());                // 初始化底层TCP/IP堆栈
    ESP_ERROR_CHECK(esp_event_loop_create_default()); // 创建默认事件循环

    esp_netif_create_default_wifi_sta(); // 创建默认的WIFI STA。

    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    esp_wifi_init(&cfg); // 初始化WiFi为WiFi驱动程序
    wifi_sta_config_t cfg_sta = {
        .ssid = "black",
        .password = "black1234",
        .threshold.authmode = WIFI_AUTH_WPA2_PSK,   //加密方式
        .pmf_cfg = {
            .capable = true,
            .required = false
        },
    };
    esp_wifi_set_config(WIFI_IF_STA, (wifi_config_t *)&cfg_sta); // 设置ESP32 STA或AP的配置

    esp_wifi_set_mode(WIFI_MODE_STA); // 设置WiFi操作模式

    // 将事件处理程序的实例注册到默认循环中           任何事件
    esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, wifi_event_handler, NULL, NULL);
    // 将事件处理程序的实例注册到默认循环中            工作站从连接的AP获得IP事件
    esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, wifi_event_handler, NULL, NULL);

    esp_wifi_start(); // 根据当前配置启动wifi

    xTaskCreate(&http_test_task, "http_test_task", 8192, NULL, 5, NULL); //问题点3: 这里参数需要设置足够大的栈大小, 否则会导致崩溃, 可以根据实测来改, 最好MAX_HTTP_OUTPUT_BUFFER大,否则可能会崩溃.
}

作者:帅得不敢出门 csdn原创谢绝转载

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

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

相关文章

佰朔资本:大盘股和小盘股的区别?大中小盘股划分标准?

一般来说&#xff0c;大盘股&#xff1a;流通市值在500亿及以上&#xff0c;中盘股&#xff1a;流通市值在100亿~500亿之间&#xff0c;小盘股&#xff1a;流通市值在100亿及以下。 留意&#xff1a;流通市值是可以上市买卖流通的股数与股价乘积&#xff0c;总市值由流通市值与…

【项目源码】终于有人将打字游戏和编程英语结合起来啦!Java初学者的福音

Hello&#xff01;各位彦祖&#xff0c;亦菲们&#xff01;又是美好的一天&#xff01;今天给大家分享一个Java项目源码&#xff1a;Java打字游戏项目源码&#xff01; 看到这里&#xff0c;你可能会说&#xff01; 一个破打字游戏有什么可神气的&#xff01;&#xff01;&…

OpenCV 图像处理中滤波技术介绍

VS2022配置OpenCV环境 关于OpenCV在VS2022上配置的教程可以参考&#xff1a;VS2022 配置OpenCV开发环境详细教程 图像处理中滤波技术 图像滤波是图像处理中的一种重要技术&#xff0c;用于改善图像质量或提取图像中的特定特征。以下是一些常见的图像滤波技术&#xff1a; 均…

LeetCode 热题100-41 二叉树的层序遍历

二叉树的层序遍历 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;[[3],[9,20],[15,7]]示例 2&…

线上预订酒店订房小程序源码系统 多商家入驻 带完整的安装代码包以及搭建部署教程

系统概述 线上预订酒店订房小程序源码系统是一款基于微信小程序开发的酒店预订系统。它充分利用了微信小程序的便捷性和普及性&#xff0c;为用户提供了一个方便、快捷的酒店预订渠道。同时&#xff0c;该系统还支持多商家入驻&#xff0c;允许不同的酒店商家在同一个平台上展…

uniapp自定义头部导航栏布局(普通版)

H5与微信小程序 通过获取系统信息和获取胶囊按钮的信息&#xff0c;得到获取标题栏高度&#xff0c;成而做好自定义头部导航栏 在微信小程序可使用 但在H5就保错&#xff0c;就需要优化 <!-- 全局custom-nav-bar组件 --> <template><view class"customN…

【Docker】Dockerfile实列-Nginx镜像构建

一、镜像构建步骤 实验准备&#xff1a;导入centos7镜像&#xff08;因为现在docker镜像拉取不下了&#xff09; docker load -i centos-7.tar.gz 1、建立构建目录&#xff0c;编写构建文件 [rootdocker-node1 ~]# mdkir /docker [rootdocker-node1 ~]# cd /docker [rootdo…

发现一个程序员最强外设,助你高效开发早日摸鱼!

简介 最近公司的副屏有点问题&#xff0c;经常屏闪&#xff0c;无意中和媳妇儿吐槽了几句。没想到&#xff0c;生日的时候&#xff0c;居然收到了她的礼物&#xff1a; 看到「程序员专用」的时候&#xff0c;我很开心的对媳妇儿表示了感谢&#xff0c;但内心第一反应是&#x…

1DM+ v17.1 修改版 — 多线程下载管理工具(高效稳定)

1DM 是一款适用于安卓设备的下载管理工具&#xff0c;支持多线程下载&#xff0c;可以加快下载速度。具备自动识别下载链接、断点续传、下载任务管理和文件浏览等功能。此修改版由 Balatan 制作&#xff0c;无需 root 或 Lucky Patcher&#xff0c;禁用不必要的权限和功能&…

学习之SQL语句

SQL通用语法 1、SQL语句可以单行或者多行书写&#xff0c;以分号结尾 2、SQL语句可以使用空格或者缩进增强语句的可读性 3、MySQL数据库的SQL语句不区分大小写&#xff0c;关键字建议使用大写 4、注释&#xff1a; 单行注释&#xff1a;-- 注释内容 或 # 注释内容&#xff08;…

【百度-APP相关安卓开发】

百度-APP相关安卓开发 安卓四大组件activaty生命周期 启动模式一个Activity的生命周期主要有四种状态&#xff1a;Activity周期Activity的启动模式&#xff1a;广播接收器 线程多线程 线程池进程 线程 携程进程与线程比较协程与线程比较 进程间通信方式和区别Mysql和Redis区别T…

【Python】--- 基础语法(上)

Welcome to 9ilks Code World (๑•́ ₃ •̀๑) 个人主页: 9ilk (๑•́ ₃ •̀๑) 文章专栏&#xff1a; Python 本篇博客博主将分享一些python的基础语法。 &#x1f3e0; 常量和表达式 我们可以把Python当成一个计算器,进行一些简单的算术运算 print(1 …

九芯电子:派对酒吧音箱灯光语音控制方案的优选

随着科技的发展以及智能AI的兴起&#xff0c;人们对交互体验的需求不断增长&#xff0c;派对酒吧音箱灯光语音控制方案是人机交互信息载体。‌九芯电子的NRK3301芯片成为了派对酒吧音箱灯光语音控制方案的理想选择。‌ NRK3301芯片是一款高性能、低成本的32位语音识别芯片&…

windows上传文件精准包含技巧

目录 环境搭建 原理 绕过 结果 环境搭建 需要在php.ini开启upload_tmp_dir选项 这里需要对C:\Windows\Temp有写入权限 文件上传页面 文件包含页面 原理 利用文件上传产生的缓存文件进行命令执行&#xff0c;从而getshell 绕过 你上传文件的时候会生成临时文件,我们需要…

vue3中使用高德地图天气信息

注册一个key 和安全密钥 index.html中 使用script标签 引入生成的key和秘钥 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><link rel"icon" href"/favicon.ico" /><meta name&q…

吐血整理(最全论文指令手册),还有 ChatGPT 3.5/4.0 新手使用手册~ 【亲测好用】

今天给大家分享下论文润色、降重、写作的GPT指令提示词&#xff0c;按论文步骤整理 让你的文章更加有逻辑且通顺&#xff0c;助力快速完成论文&#xff0c;相信对你有帮助~ 一、论文写作润色指令 1、写作选题指令 ① 确定研究对象 我是一名【XXXXX】&#xff0c;请从以下素…

叉车7寸两路一体机介绍

叉车7寸两路一体机产品介绍&#xff1a; 1.前后高清双录&#xff1a;能够同时录制叉车行驶过程中的前方和后方影像&#xff0c;提供全面的视觉监控‌。 2.倒车盲区影像&#xff1a;特别针对倒车时的盲区进行影像捕捉&#xff0c;提高倒车安全性‌。 3.技术参数‌&#xff1a; …

以小搏大:Salesforce 十亿参数模型表现超过ChatGPT

小模型的强势崛&#xff1a;轻量化AI如何以高效表现撼动大型模型的统治&#xff01; ©作者|DWT 来源|神州问学 导读 近年来&#xff0c;人工智能领域的迅猛发展使得大型语言模型&#xff08;LLM&#xff09;成为了焦点。这些模型&#xff0c;如OpenAI的GPT-4和Google的…

展会直击 | 美格智能亮相IOTE 2024第二十二届国际物联网展·深圳站

IOTE 2024第二十二届国际物联网展深圳站于2024年8月28日—30日在深圳国际会展中心&#xff08;宝安&#xff09;开展&#xff0c;美格智能携最新的5G/4G AIoT模组与物联网行业解决方案精彩亮相&#xff0c;持续为客户带来通信技术、AI智能方面的创新产品和创新技术解决方案&…

养宠物家里有浮毛怎么办?口碑相传优质浮毛空气净化器汇总

有没有养猫五年以上还是单猫的铲屎官&#xff1f;能不能分享一下怎么才能控制住不养新猫。 从我养的第一只猫长大开始&#xff0c;看到别人家的小幼猫自己也控制不住的想养。到现在已经陆陆续续养了7只了&#xff0c;前段时间看楼下流浪的小三花差点又没忍住...要不是那段时间…