esp32-c3写一个收集附近 WiFi 和蓝牙信号通过

下面给你一个基于 ESP-IDF(v5.x) 的完整示例:在 ESP32-C3 上同时扫描附近 Wi-Fi 与蓝牙(BLE)广播,把结果以 JSON 结构统一输出到串口,并且可可选通过 MQTT 上报到服务器(打开一个宏即可)。日志默认中文。示例考虑了功耗与速率限制,避免长时间占用射频。


功能概述

  • Wi-Fi 扫描:主动/被动可选,返回 SSID、BSSID、信道、RSSI、加密类型。

  • BLE 扫描(NimBLE):解析设备地址、RSSI、广告类型、部分厂商数据。

  • 统一打包 JSON:每个周期输出一帧 {ts, wifi_list, ble_list}

  • MQTT 可选上报:定义 ENABLE_MQTT 后,会将 JSON 发布到 scan/uplink 主题。

  • 节流与功耗:可配置扫描周期、Wi-Fi dwell time、BLE 扫描窗口/间隔;支持在两次扫描间隙小休眠。


目录结构(示例工程)

scaniot/├─ main/│   ├─ CMakeLists.txt│   └─ app_main.c├─ CMakeLists.txt└─ sdkconfig.defaults   (可选:预置扫描/MQTT参数)

main/CMakeLists.txt

idf_component_register(SRCS "app_main.c"INCLUDE_DIRS ".")

顶层 CMakeLists.txt

cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(scaniot)

app_main.c

复制即可编译;根据注释修改 Wi-Fi/MQTT 参数。

#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include <time.h>#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"#include "esp_event.h"
#include "esp_log.h"
#include "esp_system.h"
#include "esp_err.h"
#include "nvs_flash.h"#include "esp_wifi.h"
#include "esp_netif.h"#include "cJSON.h"// ---- 可选使能 MQTT 上报 ----
#define ENABLE_MQTT 1   // 1=启用MQTT上报;0=仅串口输出#if ENABLE_MQTT
#include "mqtt_client.h"
#endif// ---- NimBLE BLE 扫描 ----
#include "nimble/nimble_port.h"
#include "nimble/nimble_port_freertos.h"
#include "host/ble_hs.h"
#include "host/ble_gap.h"
#include "host/util/util.h"static const char *TAG = "ScanIOT";// ====== 可配参数 ======
#define WIFI_SCAN_ACTIVE         1          // 1主动扫描 0被动扫描
#define WIFI_SCAN_MAX_AP         24         // 单次最多AP记录
#define WIFI_SCAN_CHANNEL_TIME_MS 110       // 主动扫描每信道停留(ms)// BLE 扫描参数(窗口/间隔单位均为 0.625ms)
#define BLE_SCAN_ITVL            0x0060     // 60 * 0.625ms = 37.5ms
#define BLE_SCAN_WINDOW          0x0030     // 30 * 0.625ms = 18.75ms
#define BLE_SCAN_DURATION_SEC    5          // 每轮BLE扫描时长(s)#define SCAN_PERIOD_SEC          15         // 每轮合并扫描周期(s)// Wi-Fi 连接(若需要MQTT):
static const char *WIFI_SSID = "YourAP";
static const char *WIFI_PASS = "YourPassword";// MQTT 参数:
#if ENABLE_MQTT
static const char *MQTT_BROKER_URI = "mqtt://192.168.1.100:1883";
static const char *MQTT_TOPIC      = "scan/uplink";
static esp_mqtt_client_handle_t s_mqtt = NULL;
#endif// ====== 实用:时间戳 ======
static int64_t epoch_millis(void) {struct timespec ts;clock_gettime(CLOCK_REALTIME, &ts);return (int64_t)ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
}// ====== BLE 扫描收集 ======
typedef struct {char addr[18];int rssi;uint8_t adv_type;char name[32];
} ble_item_t;#define BLE_LIST_MAX 64
static ble_item_t g_ble_list[BLE_LIST_MAX];
static int g_ble_cnt = 0;// 提取设备名(若有)
static void parse_name_from_adv(const uint8_t *data, uint8_t len, char out[32]) {out[0] = 0;uint8_t i = 0;while (i + 1 < len) {uint8_t l = data[i];if (l == 0 || i + l >= len) break;uint8_t type = data[i+1];if (type == 0x09 || type == 0x08) { // Complete/Shortened Local Nameuint8_t copy = l - 1;if (copy > 31) copy = 31;memcpy(out, &data[i+2], copy);out[copy] = 0;return;}i += (l + 1);}
}static int ble_gap_event_cb(struct ble_gap_event *event, void *arg) {switch (event->type) {case BLE_GAP_EVENT_DISC:if (g_ble_cnt < BLE_LIST_MAX) {ble_item_t *it = &g_ble_list[g_ble_cnt++];uint8_t addr[6];ble_addr_t a = event->disc.addr;memcpy(addr, a.val, 6);snprintf(it->addr, sizeof(it->addr),"%02X:%02X:%02X:%02X:%02X:%02X",addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]);it->rssi = event->disc.rssi;it->adv_type = event->disc.event_type;parse_name_from_adv(event->disc.data, event->disc.length_data, it->name);}return 0;default:return 0;}
}static void ble_host_sync(void) {// 设定随机地址(如需要)ble_hs_id_infer_auto(0, NULL);
}static void ble_host_task(void *param) {nimble_port_run(); // 不会返回nimble_port_freertos_deinit();
}// 启动一轮 BLE 扫描
static esp_err_t do_ble_scan_seconds(int duration_sec) {g_ble_cnt = 0;struct ble_gap_disc_params params = {.itvl = BLE_SCAN_ITVL,.window = BLE_SCAN_WINDOW,.filter_policy = 0,.passive = 0,.limited = 0,.filter_duplicates = 1,};int rc = ble_gap_disc(BLE_OWN_ADDR_PUBLIC, duration_sec * 1000, &params, ble_gap_event_cb, NULL);if (rc != 0) {ESP_LOGE(TAG, "BLE scan start failed rc=%d", rc);return ESP_FAIL;}// 简单等待扫描结束vTaskDelay(pdMS_TO_TICKS(duration_sec * 1000));ble_gap_disc_cancel();return ESP_OK;
}// ====== Wi-Fi 初始化/扫描 ======
static EventGroupHandle_t s_wifi_evt;
#define WIFI_EVT_CONNECTED BIT0static void wifi_event_handler(void* arg, esp_event_base_t base, int32_t id, void* data) {if (base == WIFI_EVENT && id == WIFI_EVENT_STA_START) {esp_wifi_connect();} else if (base == WIFI_EVENT && id == WIFI_EVENT_STA_DISCONNECTED) {xEventGroupClearBits(s_wifi_evt, WIFI_EVT_CONNECTED);ESP_LOGW(TAG, "Wi-Fi断开,重连中…");esp_wifi_connect();} else if (base == IP_EVENT && id == IP_EVENT_STA_GOT_IP) {xEventGroupSetBits(s_wifi_evt, WIFI_EVT_CONNECTED);ESP_LOGI(TAG, "已获取IP");}
}static void wifi_init_sta(void) {ESP_ERROR_CHECK(esp_netif_init());ESP_ERROR_CHECK(esp_event_loop_create_default());esp_netif_create_default_wifi_sta();wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();ESP_ERROR_CHECK(esp_wifi_init(&cfg));s_wifi_evt = xEventGroupCreate();ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL));ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &wifi_event_handler, NULL));wifi_config_t wc = {0};strncpy((char*)wc.sta.ssid, WIFI_SSID, sizeof(wc.sta.ssid));strncpy((char*)wc.sta.password, WIFI_PASS, sizeof(wc.sta.password));wc.sta.threshold.authmode = WIFI_AUTH_WPA2_PSK;wc.sta.sae_pwe_h2e = WPA3_SAE_PWE_BOTH;ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wc));ESP_ERROR_CHECK(esp_wifi_start());
}static int wifi_scan_collect(cJSON *wifi_arr) {wifi_scan_config_t sc = {0};
#if WIFI_SCAN_ACTIVEsc.scan_type = WIFI_SCAN_TYPE_ACTIVE;sc.scan_time.active.min = WIFI_SCAN_CHANNEL_TIME_MS;sc.scan_time.active.max = WIFI_SCAN_CHANNEL_TIME_MS + 40;
#elsesc.scan_type = WIFI_SCAN_TYPE_PASSIVE;sc.scan_time.passive = WIFI_SCAN_CHANNEL_TIME_MS + 60;
#endifESP_ERROR_CHECK(esp_wifi_scan_start(&sc, true));uint16_t ap_num = WIFI_SCAN_MAX_AP;wifi_ap_record_t aps[WIFI_SCAN_MAX_AP];ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&ap_num, aps));for (int i = 0; i < ap_num; ++i) {cJSON *item = cJSON_CreateObject();cJSON_AddStringToObject(item, "ssid", (const char*)aps[i].ssid);char bssid[18];snprintf(bssid, sizeof(bssid), "%02X:%02X:%02X:%02X:%02X:%02X",aps[i].bssid[0], aps[i].bssid[1], aps[i].bssid[2],aps[i].bssid[3], aps[i].bssid[4], aps[i].bssid[5]);cJSON_AddStringToObject(item, "bssid", bssid);cJSON_AddNumberToObject(item, "rssi", aps[i].rssi);cJSON_AddNumberToObject(item, "primary", aps[i].primary);cJSON_AddNumberToObject(item, "auth", aps[i].authmode);cJSON_AddItemToArray(wifi_arr, item);}return ap_num;
}// ====== MQTT(可选) ======
#if ENABLE_MQTT
static void mqtt_start(void) {esp_mqtt_client_config_t cfg = {.broker.address.uri = MQTT_BROKER_URI,.session.protocol_ver = MQTT_PROTOCOL_V_3_1_1,.credentials.client_id = "esp32c3-scanner",.task.priority = 5,};s_mqtt = esp_mqtt_client_init(&cfg);esp_mqtt_client_start(s_mqtt);
}static void mqtt_publish_json(const char *topic, const char *json) {if (!s_mqtt) return;int msg_id = esp_mqtt_client_publish(s_mqtt, topic, json, 0, 0, 0);if (msg_id >= 0) {ESP_LOGI(TAG, "MQTT已发布,msg_id=%d, bytes=%d", msg_id, (int)strlen(json));} else {ESP_LOGW(TAG, "MQTT发布失败");}
}
#endif// ====== 主任务:合并扫描并输出/上报 ======
static void scan_cycle_task(void *arg) {while (1) {int64_t start_ms = epoch_millis();ESP_LOGI(TAG, "====== 新一轮扫描开始 ======");// 1) BLEESP_LOGI(TAG, "开始 BLE 扫描 %ds…", BLE_SCAN_DURATION_SEC);if (do_ble_scan_seconds(BLE_SCAN_DURATION_SEC) != ESP_OK) {ESP_LOGW(TAG, "BLE 扫描失败");}// 2) Wi-FicJSON *root = cJSON_CreateObject();cJSON_AddNumberToObject(root, "ts", (double)(epoch_millis()));cJSON *wifi_arr = cJSON_CreateArray();int wifi_cnt = wifi_scan_collect(wifi_arr);cJSON_AddItemToObject(root, "wifi_list", wifi_arr);cJSON *ble_arr = cJSON_CreateArray();for (int i = 0; i < g_ble_cnt; ++i) {cJSON *o = cJSON_CreateObject();cJSON_AddStringToObject(o, "addr", g_ble_list[i].addr);cJSON_AddNumberToObject(o, "rssi", g_ble_list[i].rssi);cJSON_AddNumberToObject(o, "adv_type", g_ble_list[i].adv_type);if (g_ble_list[i].name[0]) {cJSON_AddStringToObject(o, "name", g_ble_list[i].name);}cJSON_AddItemToArray(ble_arr, o);}cJSON_AddItemToObject(root, "ble_list", ble_arr);char *json = cJSON_PrintUnformatted(root);// 串口输出printf("%s\n", json);// 可选:MQTT上报#if ENABLE_MQTTmqtt_publish_json(MQTT_TOPIC, json);#endifcJSON_Delete(root);free(json);int64_t elapsed = epoch_millis() - start_ms;int64_t sleep_ms = SCAN_PERIOD_SEC * 1000 - elapsed;if (sleep_ms < 0) sleep_ms = 0;ESP_LOGI(TAG, "本轮完成:WiFi=%d, BLE=%d,用时=%" PRId64 " ms,休息=%" PRId64 " ms",wifi_cnt, g_ble_cnt, elapsed, sleep_ms);vTaskDelay(pdMS_TO_TICKS((uint32_t)sleep_ms));}
}// ====== NimBLE 初始化 ======
static void ble_init(void) {ESP_ERROR_CHECK(nimble_port_init());ble_hs_cfg.reset_cb = NULL;ble_hs_cfg.sync_cb  = ble_host_sync;// 可设置GAP首选参数等…nimble_port_freertos_init(ble_host_task);
}// ====== app_main ======
void app_main(void) {esp_err_t ret = nvs_flash_init();if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {ESP_ERROR_CHECK(nvs_flash_erase());ESP_ERROR_CHECK(nvs_flash_init());}ESP_LOGI(TAG, "系统启动");// 初始化 BLE Hostble_init();// 若启用 MQTT,需要联网
#if ENABLE_MQTTwifi_init_sta();// 等待联网(最多10秒)if (xEventGroupWaitBits(s_wifi_evt, WIFI_EVT_CONNECTED, false, true, pdMS_TO_TICKS(10000)) == 0) {ESP_LOGW(TAG, "10秒内未联网,后续只串口输出。");} else {mqtt_start();}
#else// 即便不联网也可以做 Wi-Fi 扫描:需要初始化 netif + wifi,但无需配置AP信息ESP_ERROR_CHECK(esp_netif_init());ESP_ERROR_CHECK(esp_event_loop_create_default());esp_netif_create_default_wifi_sta();wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();ESP_ERROR_CHECK(esp_wifi_init(&cfg));ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));ESP_ERROR_CHECK(esp_wifi_start());
#endifxTaskCreatePinnedToCore(scan_cycle_task, "scan_cycle", 6144, NULL, 5, NULL, 0);
}

sdkconfig 关键点(如用 menuconfig 配)

  • Component config -> Bluetooth

    • 选择 NimBLE(而非 Bluedroid)

    • 适度调低 NimBLE max connections,保守内存

  • Component config -> Wi-Fi

    • 若仅扫描,可不开 Wi-Fi NVS flash 节省写入

  • Partition Table

    • 默认 factory 足够;如启用 OTA/MQTT 大日志,可适当放宽 nvs/phy


上位机示例输出(一行一帧 JSON)

{"ts": 1731285230123,"wifi_list":[{"ssid":"Home","bssid":"AA:BB:CC:DD:EE:FF","rssi":-45,"primary":1,"auth":3}, ...],"ble_list":[{"addr":"12:34:56:78:9A:BC","rssi":-67,"adv_type":0,"name":"MiBand"}, ...]
}

调优建议

  1. 射频复用与时间片:示例采用“先 BLE 后 Wi-Fi”的顺序,避免两者同时占用 RF,减少丢包。

  2. 速率限制SCAN_PERIOD_SEC ≥ 10s 较稳妥,过于频繁会影响系统与空口。

  3. 功耗:将 BLE_SCAN_WINDOW 设为 BLE_SCAN_ITVL * 0.5~0.6,并在两轮之间 vTaskDelay。离线场景可考虑 esp_light_sleep_start() 做轻睡。

  4. 数据量:可为 wifi_list/ble_list 设置 RSSI 阈值过滤(如 < -90dBm 丢弃),或限制最大数量。

  5. MQTT 可靠性:生产环境请启用 session.keepalive、LWT、QoS1/2 与重连回退。

  6. 合规性:采集与上报他人设备信息需遵守当地法律法规与隐私政策;生产前务必征得授权。


如果你希望把上报方式改为 HTTP(S) / WebSocket,或者把Wi-Fi 凭据用 BluFi/配网 App 来下发(你常用的 CozyLife / BluFi 流程),我可以直接把上面工程改成对应版本,并补上 sdkconfig.defaults 与分区表。

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

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

相关文章

文心大模型 X1.1:百度交出的“新深度思考”答卷

文心大模型 X1.1&#xff1a;百度交出的“新深度思考”答卷 2025年9月9日&#xff0c;WAVE SUMMIT 2025深度学习开发者大会在北京正式召开&#xff0c;由深度学习技术及应用国家工程研究中心主办&#xff0c;百度飞桨与文心大模型联合承办。大会上&#xff0c;百度正式发布了基…

开始 ComfyUI 的 AI 绘图之旅-Flux.1图生图(八)

文章标题一、Flux Kontext Dev1.关于 FLUX.1 Kontext Dev1.1 版本说明1.2 工作流说明1.3 模型下载2.Flux.1 Kontext Dev 工作流2.1 工作流及输入图片下载2.2 按步骤完成工作流的运行3.Flux Kontext 提示词技巧3.1 基础修改3.2 风格转换3.3 角色一致性3.4 文本编辑4.常见问题解决…

Java 生成微信小程序二维码

1. java 二维码生成工具类import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONObject; import com.pdatao.api.controller.file.FileController; import com.pdatao.api.error.CommunityException; import org.apache.commons.io.IOUtils; import org.springframe…

智慧健康触手可及:AI健康小屋——未来健康管理的全能守护者

AI健康小屋&#xff0c;这座融合人工智能、物联网与医疗科技的“健康堡垒”&#xff0c;正悄然重构健康管理生态。它以科技为引擎&#xff0c;将专业医疗资源下沉至社区、企业、家庭&#xff0c;通过智能检测、精准分析、个性化干预&#xff0c;实现从疾病治疗到主动预防的健康…

[工作表控件19] 验证规则实战:如何用正则表达式规范业务输入?

在企业应用中,数据准确性至关重要。工作表控件通过“验证规则”能力,支持在文本字段和附件字段中使用正则表达式(RegEx)进行格式校验。它能帮助开发者轻松实现邮箱、身份证号、车牌号、URL 等格式的高效验证,大幅提升数据质量与表单使用体验。 一、官方功能介绍与基础能力…

uniapp分包实现

关于分包优化的说明 在对应平台的配置下添加"optimization":{"subPackages":true}开启分包优化 目前只支持mp-weixin、mp-qq、mp-baidu、mp-toutiao、mp-kuaishou的分包优化 分包优化具体逻辑&#xff1a; 静态文件&#xff1a;分包下支持 static 等静态…

ctfshow_web14------(PHP+switch case 穿透+SQL注入+文件读取)

题目&#xff1a;解释&#xff1a;$c intval($_GET[c]); //获取整数值 6sleep($c);//延迟执行当前脚本若干秒。提示一下哈没有break会接着执行下面的但是像是44444&#xff0c;555555,sleep的时间太久我们用3进入here_1s_your_f1ag.php是一个查询页面&#xff0c;sql注入查看源…

linux x86_64中打包qt

下载安装 地址: Releases linuxdeploy/linuxdeploy mv linuxdeploy-x86_64.AppImage linuxdeployqtchmod 777 linuxdeployqtsudo mv linuxdeployqt /usr/local/bin/linuxdeployqt --version报错 Applmage默认依赖FUSE&#xff0c;需要挂载自身为虚拟文件系统才能运行, ubuntu…

华为昇腾CANN开发实战:算子自定义与模型压缩技术指南

点击 “AladdinEdu&#xff0c;同学们用得起的【H卡】算力平台”&#xff0c;注册即送-H卡级别算力&#xff0c;80G大显存&#xff0c;按量计费&#xff0c;灵活弹性&#xff0c;顶级配置&#xff0c;学生更享专属优惠。 摘要 随着人工智能技术的飞速发展&#xff0c;越来越多…

Vue3源码reactivity响应式篇之reactive响应式对象的track与trigger

概览 在BaseReactiveHandler类的get方法中&#xff0c;有如下代码块if (!isReadonly2){track(target, "get", key);}&#xff0c;这表示通过reactive、shallowReactive创建的响应式对象&#xff0c;非只读的&#xff0c;当读取代理对象proxyTarget的某个属性key时&am…

VRRP 多节点工作原理

VRRP 多节点工作原理 基本概念 VRRP 的设计初衷是给一组节点提供一个 虚拟路由器&#xff0c;对外只表现出一个 VIP。协议规定&#xff1a;同一个 VRRP 实例 下始终只有 一个 Master 持有 VIP&#xff0c;其它全部是 Backup。 Master → 持有 VIP&#xff0c;负责转发流量到Mas…

Gradio全解11——Streaming:流式传输的视频应用(9)——使用FastRTC+Gemini创建沉浸式音频+视频的艺术评论家

Gradio全解11——Streaming&#xff1a;流式传输的视频应用&#xff08;9&#xff09;——使用FastRTCGemini创建沉浸式音频视频的艺术评论家11.9 使用FastRTCGemini创建实时沉浸式音频视频的艺术评论家11.9.1 准备工作及音频图像编码器1. 项目说明及准备工作2. 音频和图像编码…

Django入门笔记

Python知识点&#xff1a;函数、面向对象。前端开发&#xff1a;HTML、CSS、JavaScript、jQuery、BootStrap。MySQL数据库。Python的Web框架&#xff1a;Flask&#xff0c;自身短小精悍 第三方组件。Django&#xff0c;内部已集成了很多组件 第三方组件。【主要】1.安装djang…

当Claude Code失灵,Qwen Code能否成为你的救星?

当Claude Code失灵&#xff0c;Qwen Code能否成为你的救星&#xff1f; 一、开头&#xff1a;点明困境&#xff0c;引出主角 作为一个大模型博主&#xff0c;日常工作中我经常会使用各种 AI 工具来提高效率&#xff0c;Claude Code 就是我之前非常依赖的一款代码生成助手 。它…

Go语言快速入门教程(JAVA转go)——1 概述

优势 第一个理由&#xff1a;对初学者足够友善&#xff0c;能够快速上手。 业界都公认&#xff1a;Go 是一种非常简单的语言。Go 的设计者们在发布 Go 1.0 版本和兼容性规范后&#xff0c;似乎就把主要精力放在精心打磨 Go 的实现、改进语言周边工具链&#xff0c;还有提升 Go …

【Rust多进程】征服CPU的艺术:Rust多进程实战指南

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

OpenCV 高阶实战:图像直方图与掩码图像深度解析

目录 一、图像直方图&#xff1a;读懂图像的 “像素分布报告” 1. 什么是图像直方图&#xff1f; 2. 图像直方图的核心作用 &#xff08;1&#xff09;分析亮度分布 &#xff08;2&#xff09;判断对比度高低 &#xff08;3&#xff09;辅助图像增强与阈值分割 &#xf…

基于stm32的家庭安全监测系统设计

若该文为原创文章&#xff0c;转载请注明原文出处。一、引言&#xff08;一&#xff09;研究背景及意义背景&#xff1a;随着智能家居概念的普及&#xff0c;人们对家庭安全、舒适度和节能提出了更高要求。传统安防系统功能单一、各系统独立&#xff0c;缺乏联动和远程管理能力…

Oracle体系结构-控制文件(Control Files)

一、 原理 (Principle) 核心定位&#xff1a; 控制文件是一个小型的二进制文件&#xff0c;由 Oracle 实例在启动和操作过程中持续读写。它是数据库物理结构的权威记录。数据库无法启动或正常操作时&#xff0c;如果无法访问控制文件&#xff0c;实例将无法识别数据文件和重做日…

路由 下一跳 网关 两个不同网段的ip如何通过路由器互通

路由 (Routing)核心思想&#xff1a;路径选择是什么&#xff1f; 路由是指数据包从源主机传输到目标主机的整个过程。这个过程就像寄快递&#xff1a;你需要决定包裹经过哪些中转站才能最终到达收件人手里。做什么&#xff1f; 网络中的设备&#xff08;主要是路由器&#xff0…