【SPP】蓝牙 SDP 协议在SPP中的互操作性解析
在蓝牙通信体系中,服务发现协议(SDP, Service Discovery Protocol)扮演着 "服务目录" 的核心角色。对于串口通信协议(SPP, Serial Port Profile)而言,SDP 服务记录是设备间建立串口连接的基础:主设备(DevA)通过解析从设备(DevB)的 SDP 记录,获取 RFCOMM 通道号、协议版本等关键信息。本文将深度解析 SPP 中 SDP 的互操作性要求,结合协议规范与实战经验,为开发符合蓝牙 SIG 标准的串口设备提供完整指南。
一、SPP 服务记录的核心要素
SDP是蓝牙设备互联的"黄页系统",其核心价值在于建立设备间的服务认知桥梁。在Serial Port Profile中,SDP承担着关键的服务宣告与发现职能,特别是在设备角色划分明确的场景下(DevA作为客户端,DevB作为服务端),其实现细节直接影响着设备互操作性。
1.1 服务记录结构总览
每个服务记录由一组属性(Attribute)构成,属性包含:
-
属性ID:16位无符号整数,唯一标识属性类型(如服务类UUID为0x0001)。
-
属性值:可变长度数据,具体含义由属性ID决定(如RFCOMM通道号为Uint8类型)。
DevB 的 SDP 数据库中,SPP 服务记录包含以下必选(M)和可选(O)属性:
1.2 必选属性深度解析
1.2.1 ServiceClassIDList(服务类标识)
-
作用:标识设备支持的服务类型
-
规范:必须包含
SerialPort
服务类(UUID 0x1101) -
扩展:可添加其他服务类(如 PANU:0x1115)
1.2.2 ProtocolDescriptorList(协议栈描述)
// 协议栈结构示例(WireFormat格式)
ProtocolDescriptorList = [{ UUID: L2CAP (0x0100) },{ UUID: RFCOMM (0x0003), Parameters: [ ServerChannel (N) ] }
]
-
L2CAP 层:固定使用 UUID 0x0100
-
RFCOMM 层:固定使用 UUID 0x0003,附带通道号参数
1.2.3 BluetoothProfileDescriptorList(配置文件描述)
-
版本标识:
-
v1.2+:必须包含
ProfileVersion 0x0102
-
旧设备(无此属性):视为支持 v1.1 及以下
-
兼容性设计:DevA 应优先选择包含 0x0102 的设备,旧设备需降级处理
1.3 可选属性优化实践
1.3.1 ServiceName(服务名称)
-
多语言支持:
// 语言编码示例(中文)
LanguageBaseAttributeIDList = [0x0804] // zh-CN
ServiceName = "蓝牙串口 (COM5)"
-
最佳实践:提供描述性名称(如 "Printer Serial Port")
1.3.2 其他扩展属性
-
BrowseGroupList:分组分类(如 0x0001:公共设备)
-
SupportedFeatures:扩展功能标记(如流控支持)
1.4 SDP的核心定位
SDP是蓝牙协议栈中的“服务发现层”,其作用类似于互联网中的DNS,但专为蓝牙设备设计。它定义了设备如何发现网络中其他设备提供的服务,并获取服务的详细属性。在蓝牙通信中,任何设备在建立连接前,必须通过SDP查询对方支持的服务类型及参数,这是实现设备间互操作性的基础。
二、SDP 服务发现流程
2.1 交互角色定义
设备角色 | 协议角色 | 操作权限 |
DevA | SDP 客户端 | 发起服务查询、浏览、属性读取 |
DevB | SDP 服务器 | 响应查询、提供服务记录 |
2.2 标准查询流程
其工作流程可分为三步:
-
服务搜索:客户端发送包含目标服务UUID的请求,服务端返回匹配的服务记录句柄。
-
属性查询:客户端通过句柄进一步请求服务的详细属性(如协议类型、通道号等)。
-
服务浏览:客户端可遍历服务端的所有服务类别,无需预先知道具体UUID。
2.3 关键协议步骤
-
L2CAP 连接建立:
-
PSM 固定为 0x0001(SDP 服务端口)
-
MTU 协商:建议≥512 bytes(适应长服务记录)
-
-
服务搜索(ServiceSearchRequest):
Request: ServiceClassIDList = [0x1101]
Response: ServiceRecordHandleList
-
记录读取(ServiceRecordReadByHandleRequest):获取完整服务记录(包含所有属性)
-
协议参数解析:
-
提取 RFCOMM 通道号(ProtocolSpecificParameter0)
-
验证 Profile 版本(BluetoothProfileDescriptorList)
-
三、服务记录的实现规范与示例
3.1 典型服务记录示例(WireFormat)
ServiceRecord(ServiceClassIDList(UUID(0x1101) // SerialPort),ProtocolDescriptorList(L2CAP(0x0100),RFCOMM(0x0003, ServerChannel(5))),BluetoothProfileDescriptorList(UUID(0x1101),ProfileVersion(0x0102)),ServiceName("BT Serial Port (COM5)"),LanguageBaseAttributeIDList(0x0409) // en-US
)
3.2 版本兼容性处理
设备类型 | BluetoothProfileDescriptorList 存在 | 支持版本 | DevA 处理策略 |
新设备(v1.2+) | 是(0x0102) | v1.2+ | 使用完整功能 |
旧设备(v1.1) | 否 | v1.1 | 禁用 v1.2 + 专属功能(如 QoS) |
开发建议:实现版本协商机制,兼容新旧设备
四、多语言支持实现
4.1 语言编码规范
-
LanguageBaseAttributeID:ISO 639-1 语言代码 + ISO 3166-1 国家代码
-
示例:
-
中文(中国):0x0804
-
英语(美国):0x0409
-
4.2 多语言服务记录结构
五、SDP 实现最佳实践
5.1 通道号分配策略
-
范围:1~30(RFCOMM 规范限制)
-
动态分配:
// 伪代码:通道号分配逻辑
uint8_t allocate_rfcomm_channel() {for (int i=1; i<=30; i++) {if (channel_free(i)) return i;}return 0xFF; // 分配失败
}
5.2 服务记录优化
-
最小化必选属性:确保 M 属性完整
-
扩展属性分组:使用 BrowseGroup 分类(如 0x1001:串口设备组)
-
版本声明:强制包含 0x0102(v1.2 + 设备)
5.3 共存设备配置
5.4 SDP与SPP的协同优化策略
①服务记录的动态更新
-
场景:DevB升级SPP版本后,需更新SDP数据库中的
BluetoothProfileDescriptorList
。 -
实现:通过SDP的
SdpDB_ModifyRecord
函数更新服务记录,通知周边设备重新发现服务。
②兼容性回退机制
-
新设备连接旧设备:
-
检测
BluetoothProfileDescriptorList
是否存在。 -
若不存在,默认使用SPP v1.1协议特性(如固定通道号范围)。
-
③多语言支持扩展
-
ServiceName属性:通过
LanguageBaseAttributeIDList
支持多语言名称(如中文"COM5")。
六、协议一致性测试
6.1 必测用例
-
服务类验证:
-
包含 ServiceClassID=0x1101
-
可选类验证(如是否包含其他服务类)
-
-
协议栈验证:
-
ProtocolDescriptorList 顺序:L2CAP→RFCOMM
-
RFCOMM 通道号有效性(1~30)
-
-
版本验证:
-
v1.2 + 设备:检查 BluetoothProfileDescriptorList=0x0102
-
旧设备:检查是否无此属性
-
6.2 测试工具与方法
工具类型 | 工具示例 | 测试功能 |
协议分析仪 | Wireshark + BlueZ | 捕获 SDP 数据包,验证 WireFormat 格式 |
服务发现工具 | sdptool(Linux) | 模拟 DevA 查询,检查响应完整性 |
一致性套件 | Bluetooth PTS | 官方 SDP 互操作性认证(SIG 要求) |
命令行测试示例(Linux)
# 查询设备00:11:22:33:44:55的SPP服务
sdptool search --bdaddr 00:11:22:33:44:55 SerialPort# 预期输出:
# Service Name: BT Serial Port (COM5)
# Service RecHandle: 0x1000
# ...
# Protocol Descriptor:
# "L2CAP" (0x0100)
# "RFCOMM" (0x0003) channel 5
七、常见问题与解决方案
7.1 通道号冲突
-
现象:多个配置文件使用相同 RFCOMM 通道
-
解决:实现通道号分配表,避免重复(如使用全局数组记录已占用通道)
7.2 服务记录过长
-
现象:超过 L2CAP MTU 导致分片传输
-
优化:
-
协商较大 MTU(如 1500 bytes)
-
精简可选属性,仅保留必要信息
-
7.3 旧设备兼容性
-
现象:DevA 无法识别无 ProfileDescriptor 的设备
-
解决:
// 版本协商逻辑
if (has_profile_descriptor(devB)) {use_version_1_2();
} else {use_version_1_1();
}
7.4 服务发现失败分析树
八、未来演进与挑战
8.1 未来演进趋势
-
低功耗SDP:BLE方向优化服务发现能耗
-
AI驱动发现:机器学习预测服务需求
-
量子安全SDP:抗量子计算加密算法整合
-
跨协议发现:Wi-Fi与蓝牙服务联合发现
8.2 服务发现的性能瓶颈
-
问题:频繁的服务搜索和属性查询可能增加延迟。
-
优化:
-
缓存机制:客户端缓存已发现的设备服务记录。
-
增量更新:服务端仅发送变更的服务记录。
-
8.3 安全性增强
-
服务访问控制:通过SDP的
SecurityDescription
属性限制服务访问权限。 -
加密传输:结合L2CAP层的加密功能,保障服务发现过程的安全性。
8.4 跨平台兼容性
-
问题:不同操作系统对SDP属性的解析可能存在差异。
-
解决方案:
-
标准化测试:使用蓝牙官方认证工具验证服务记录合规性。
-
兼容性库:封装跨平台SDP解析逻辑,屏蔽底层差异。
-
九、总结
9.1 核心要素回顾
-
服务记录:必选属性(ServiceClassID、ProtocolDescriptor、ProfileVersion)
-
发现流程:标准 SDP 查询序列(连接→搜索→读取→解析)
-
兼容性:版本协商、多语言支持、通道管理
9.2 开发 checklist
✅ 实现完整的必选 SDP 属性(M 标记)
✅ 验证 RFCOMM 通道号在 1~30 范围内
✅ 支持多语言 ServiceName(LanguageBaseAttributeID)
✅ 实现版本协商逻辑(区分 v1.1/v1.2 + 设备)
✅ 使用协议分析仪验证 WireFormat 格式正确性
十、附录:关键术语与规范引用
术语 | 解释 | 规范引用 |
SDP | 服务发现协议(Service Discovery Protocol) | 蓝牙核心规范 Vol 3, Part B |
RFCOMM | 射频通信协议(Radio Frequency Communication) | 核心规范 Vol 3, Part D |
UUID | 通用唯一标识符(Universally Unique Identifier) | 蓝牙分配号码文档 |
WireFormat | SDP 数据 WireFormat 格式 | 核心规范 Vol 3, Part B |
十一、参考文献
[1] 蓝牙核心规范(Core Specification)V6.0
[2] 串行端口配置文件(Serial Port Profile)V1.2
[3] 服务发现协议规范(SDP Specification)Vol 3, Part B
[4] 蓝牙分配号码文档(Assigned Numbers)Rev. 28
[5]《蓝牙 SDP 协议实战指南》(蓝牙技术联盟官方文档)
[6] RFCOMM 协议深度解析(BT SIG 白皮书:RFCOMM Protocol Explained)
[7] 多语言服务记录实现案例(Bluetooth SIG Interoperability Reports)
相关文章:
【SPP】蓝牙 SDP 协议在SPP中的互操作性解析
在蓝牙通信体系中,服务发现协议(SDP, Service Discovery Protocol)扮演着 "服务目录" 的核心角色。对于串口通信协议(SPP, Serial Port Profile)而言,SDP 服务记录是设备间建立串口连接的基础&am…...
本地部署vanna ai+通过http请求调用vanna
本地部署vanna ai ① 准备python环境,推荐最新的python12、13版本 ② 安装vanna库 我这里安装的python环境是python312 进入目录python312/Scripts,在该目录下的命令行窗口中输入以下命令:pip jinstall vanna pip install vanna③ 配置向…...
seq2seq
理解 transformer 中的 encoder decoder 详细的 transformer 教程见:【极速版 – 大模型入门到进阶】Transformer 文章目录 🌊 Encoder: 给一排向量输出另外一排向量🌊 Encoder vs. Decoder: multi-head attention vs. masked multi-head at…...
C++ ---- 虚继承
一、什么是虚继承 虚继承就是子类中只有一份间接父类的数据。用于解决多继承中的父类为非虚继承时出现的二义性问题,即菱形继承问题。继承方式需要加上virtual关键字。 二、虚继承的特性 以菱形继承为例: 1.不使用虚继承 根据输出的大小和关系图&…...
COMSOL多层圆片随机堆积三维模型
构建多层圆片随机堆积三维模型可用于材料、化工、土木、生物医学等多领域的研究,如复合材料设计、催化剂载体、颗粒物堆积研究等。本案例介绍在COMSOL内建立三维圆片堆积模型。 三维圆片堆积模型可采用CAD纤维密堆积3D插件建立,参数设置如图所示&#…...
PHP 开发API接口签名验证
就安全来说,所有客户端和服务器端的通信内容应该都要通过加密通道(HTTPS)传输,明文的HTTP通道将会是man-in-the- middle及其各种变种攻击的温床。所谓man-in-the-middle攻击简单讲就是指恶意的黑客可以在客户端和服务器端的明文通信通道上做手 脚&#x…...
Web开发-JavaEE应用ORM框架SQL预编译JDBCMyBatisHibernateMaven
知识点: 0、安全开发-JavaEE-构建工具-Maven 1、安全开发-JavaEE-ORM框架-JDBC 2、安全开发-JavaEE-ORM框架-Mybatis 3、安全开发-JavaEE-ORM框架-Hibernate 4、安全开发-JavaEE-ORM框架-SQL注入&预编译 一、演示案例-WEB开发-JavaEE-构建工具-Maven IDEA配置m…...
软考-数据库系统工程师第四版pdf
软考-数据库系统工程师第四版pdf git中的文件相对没有那么清楚,网盘的有高清版 github下载 这里我给出仓库地址 链接: https://github.com/yaodada123/ruankao-pdf https://github.com/yaodada123/ruankao-pdf gitee下载 https://gitee.com/yao-hengchao/ruank…...
扫描仪+文档pdf编辑器+pdf格式转换器
小扫描仪是一款集“扫描仪文档pdf编辑器pdf格式转换器”于一体的多功能扫描软件,软件功能丰富,而且目前是免费,功能包括扫描、编辑、转换三部分。 扫描:扫描的功能包括文档扫描、身份证扫描、护照扫描、书籍扫描、OCR和二维码。 扫…...
【stm32--HAL库DMA+USART+空闲中断不定长收发数据】
串口通信-Hal库实现不定长度收发,DMAUSART DMA串口STM32CUBEMX配置(工程创建)基础配置时钟配置工程配置 代码编写现象 DMA 在正式配置之前,我们先来一起简单了解一下DMA。DMA(Direct Memory Access,直接内…...
5G-A技术
最近的iOS 18.4 推送了 新功能,最引人注目的便是这个5G-A的这个功能,那什么是5G-A呢 ? 目前北京 四环内 还是有能显示出5G-A标志的。 5G-A 🌐 一句话概括: 5G-A 更快的速度 更低的延迟 更强的AI能力 更智能的网…...
Vue 组件 - 动态组件
Vue 渐进式JavaScript 框架 基于Vue2的学习笔记 - Vue 组件 - 动态组件 目录 动态组件 选项卡页面示例 更简单写法 增加输入框 弥补措施 总结 动态组件 选项卡页面示例 功能:选项卡功能,设置导航点击哪个显示相应页面。 设置三个全局组件&#…...
ffmpeg滤镜使用
ffmpeg实现画中画效果 FFmpeg中,可以通过overlay将多个视频流、多个多媒体采集设备、多个视频文件合并到一个界面中,生成画中画的效果 FFmpeg 滤镜 overlay 基本参数 x和y x坐标和Y坐标 eof action 遇到 eof表示时的处理方式,默认为重复。…...
【MVC简介-产生原因、演变历史、核心思想、组成部分、使用场景】
MVC简介 产生原因: MVC(Model-View-Controller)模式诞生于20世纪70年代,由Trygve Reenskaug在施乐帕克研究中心(Xerox PARC)为Smalltalk语言设计,目的是解决图形用户界面(GUI&…...
基于大模型的房间隔缺损手术全流程预测与方案优化研究报告
目录 一、引言 1.1 研究背景与意义 1.2 研究目的与目标 1.3 研究方法与创新点 二、房间隔缺损概述 2.1 房间隔缺损定义与分类 2.2 发病机制与病理生理 2.3 流行病学特征 三、大模型在房间隔缺损预测中的应用原理 3.1 大模型技术简介 3.2 数据收集与预处理 3.3 模型…...
什么是 CSSD?
文章目录 一、什么是 CSSD?CSSD 的职责 二、CSSD 是如何工作的?三、CSSD 为什么会重启节点?情况一:网络和存储都断联(失联)情况二:收到其他节点对自己的踢出通知(外部 fencing&#…...
uniapp APP端在线升级(简版)
设计思路: 1.版本比较:应用程序检查其当前版本与远程服务器上可用的最新版本 2. 更新状态指示:如果应用程序是不是最新的版本,则页面提示下载最新版本。 3.下载启动:通过plus.downloader.createDownload()启动新应用…...
2024年蓝桥杯Java B组省赛真题超详解析-分布式队列
问题:你需要回答在某个时刻,队列中有多少个元素具有可见性 方案:跟踪每个副节点已经同步到主节点队列的元素数量,并找出所有副节点中同步到的最少元素数量,这个数量即为所有副节点都已经同步的元素数量。 解析&#…...
Vue3入门
环境准备: node.js vscode or webstorm 哪个熟悉用哪个 这两个都是傻瓜式安装 浏览器直接搜索 下载即可 安装: 安装完node.js之后 按住快捷键 winR 打开命令提示符输入node 将显示版本信息 接着我们通过 vite 构建vue3工程 优点: 轻量快速的热重载(HMR…...
向量库(Vector Database)概述
向量库(Vector Database)概述 1. 核心概念 向量 高维空间中的数值数组,通常由模型(如BERT、ResNet)将非结构化数据(文本、图像等)转换为嵌入向量。 向量相似性 衡量方法:余弦相…...
Oracle迁移达梦遇中断?试试SQLark的断点续迁功能!
在企业级数据迁移项目中,如果迁移单表数据量超过亿行、占用空间超过100GB时,一旦遇到网络中断或迁移报错,往往需要整表重新迁移,导致效率低下,严重影响项目进度。针对这一痛点,SQLark 支持对 Oracle→DM 的…...
上海某海外视频平台Android高级工程师视频一面
问的问题比较细,有很多小细节在里面,平时真不一定会注意到,做一个备忘: 1.Object类里面有哪些方法? Object 类是 Java 中所有类的根类,它定义了一些基本方法,供所有类继承和重写1. 常用方法 1…...
基于yolov11的汽车损伤检测系统python源码+onnx模型+评估指标曲线+精美GUI界面
【算法介绍】 基于YOLOv11的汽车损伤检测系统是一种先进的计算机视觉技术,旨在快速准确地识别汽车的各种损伤类型。该系统利用YOLOv11模型的强大性能,实现了对车辆损伤的精确检测与分类。 该系统能够识别的损伤类型包括裂纹(crackÿ…...
华为IP(3)
DHCP Relay报文格式 DHCP Relay主要负责转发DHCP客户端与DHCP服务器之间的DHCP报文,所以DHCP Relay的报文格式只是把DHCP的报文部分字段做了相应的修改,报文格式没有发生变化 hops:表示当前DHCP报文经过DHCP中继的数目,该字段由…...
面试问题总结:qt工程师/c++工程师
C 语言相关问题答案 面试问题总结:qt工程师/c工程师 C 语言相关问题答案 目录基础语法与特性内存管理预处理与编译 C 相关问题答案面向对象编程模板与泛型编程STL 标准模板库 Qt 相关问题答案Qt 基础与信号槽机制Qt 界面设计与布局管理Qt 多线程与并发编程 目录 基础…...
【TS学习】(15)分布式条件特性
在 TypeScript 中,分布式条件类型(Distributive Conditional Types) 是一种特殊的行为,发生在条件类型作用于裸类型参数(Naked Type Parameter) 时。这种特性使得条件类型可以“分布”到联合类型的每个成员…...
四款高效数据报表工具 让数据分析更简单
概述 在数字化时代,企业和组织越来越依赖数据驱动决策,报表软件成为提高数据可视化能力、优化业务管理的关键工具。本文将为大家介绍四款功能强大的报表软件,帮助不同需求的企业找到合适的解决方案。 一、山海鲸报表 山海鲸报表是一款零代…...
QT 非空指针 软件奔溃
在用QT的实际项目中,出现如下现象: 运行软件再关闭软件,然后再运行软件会崩溃。等待5~10分钟,再运行软件,又正常,百思不得其解,后面找到原因是在头文件里定义指针变量时没有赋初nullptr&#x…...
图漾相机——C#语言属性设置
文章目录 前言1.示例程序说明2.SDK API功能介绍2.1 ListDevice2.2 Open2.3 OpenDeviceByIP2.4 Close2.5 DeviceStreamEnable2.6 DeviceStreamFormatDump2.7 DeviceStreamFormatConfig2.8 DeviceReadCurrentEnumData2.9 DeviceReadCalibData2.10 DeviceStreamOn2.11 DeviceStrea…...
WPF中viewmodel单例模式
1、单例模式介绍 单例模式是一种创建型设计模式,确保一个类只有一个实例,并提供一个全局访问点来获取这个实例。它常用于需要全局唯一访问点的场景,如配置管理、日志记录、数据库连接等。 2、WPF 中 ViewModel 的单例实现 在 WPF 中&#…...
AI比人脑更强,因为被植入思维模型【36】时光机理论思维
giszz的理解:据说是软银孙正义提出的一种思维模型,他利用同一时间内的地区差,通过引入技术、思维,在同一地区,形成了时间差。所谓商业模式,有时就是打空间差、时间差,信息差。 一、定义 时光机…...
SQL Server:用户权限
创建 & 删除 1. 创建用户命令整理 创建 admin2 用户 -- 在 master 数据库创建登录名 USE master; BEGINCREATE LOGIN [admin2] WITH PASSWORDNCljslrl0620!, DEFAULT_DATABASE[master], CHECK_EXPIRATIONOFF, CHECK_POLICYON; END;-- 在 db03 数据库创建用户并添加到相应…...
Qt之QTextEdit控制文本滚动, 停止滚动, 开始滚动, 鼠标控制滚动
对工作台文本框进行控制。含以下内容。详细说明在源码中可查看 至最底部停止滚动开始滚动 源码分两部分. .h文件和.cpp文件 MyTextEdit.h #ifndef MYTEXTEDIT_H #define MYTEXTEDIT_H#include <QObject> #include <QTextEdit> #include <QScrollBar> #includ…...
策略模式与元数据映射模式融合 JSR 380 验证规范实现枚举范围校验
类文件 Target({ElementType.METHOD,ElementType.FIELD,ElementType.ANNOTATION_TYPE,ElementType.CONSTRUCTOR,ElementType.PARAMETER,ElementType.TYPE_USE }) Retention(RetentionPolicy.RUNTIME) Documented Constraint(validatedBy {InEnumValidator.class, InEnumColle…...
9对象树(3)
目录 创建自定义的类,最主要的目的,是自定义一个析构函数,在析构函数中,完成打印.方便咱们看到最终的自动销毁对象的效果!!! 写完一个函数的声名之后, 按下 altenter, 在按下enter就可以自动的在对应的 cpp 文件中添加函数的定义了 内置类型,析构不会明…...
深入 OpenPDF:高级 PDF 生成与操作技巧
1 引言 1.1 项目背景 在许多企业级应用中,生成和操作 PDF 文档是一个常见的需求。PDF(Portable Document Format)因其格式统一、易于打印和分发而被广泛使用。本文将介绍如何使用 OpenPDF 库在 Java 项目中生成和操作 PDF 文档。 1.2 技术选型理由 OpenPDF:OpenPDF 是一…...
电脑屏幕亮度随心控,在Windows上自由调整屏幕亮度的方法
调整电脑屏幕的亮度对于保护视力和适应不同环境光线条件非常重要。无论是在白天强光下还是夜晚昏暗环境中,合适的屏幕亮度都能让您的眼睛更加舒适。本文中简鹿办公小编将向您介绍几种在 Windows 系统中调整屏幕亮度的方法。 方法一:使用快捷键 大多数笔…...
Navicat导出mysql数据库表结构说明到excel、word,单表导出方式记录
目前只找到一张一张表导出的方式 使用information_schema传入表名查询 字段名根据需要自行删减,一般保留序号、字段名、类型、说明就行 SELECT COLUMNS.ORDINAL_POSITION AS 序号, COLUMNS.COLUMN_NAME AS 字段名, COLUMNS.COLUMN_TYPE AS 类型(长度), COLUMNS.N…...
【C++笔记】C++常见二叉树OJ和拓扑排序
【C笔记】C常见二叉树OJ和拓扑排序 🔥个人主页:大白的编程日记 🔥专栏:C笔记 文章目录 【C笔记】C常见二叉树OJ和拓扑排序前言一.二叉树OJ1.1 根据二叉树创建字符串1.2 二叉树的层序遍历1.3 二叉树的最近公共祖先1.4 将二叉搜索…...
ARM-----数据处理、异常处理、模式切换
实列一: 1. 异常向量表 area reset, code, readonly code32 entry area reset, code, readonly:定义一个名为reset的代码区域,只读。 code32:指示编译器生成32位ARM指令。 entry:标记程序的入口点。 2. 程序入口…...
mapbox基础,使用geojson加载line线图层,实现铁路黑白间隔效果
👨⚕️ 主页: gis分享者 👨⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言1.1 ☘️mapboxgl.Map 地图对象1.2 ☘️mapboxgl.Map style属性1.3 ☘️line线图层样式二、🍀使用geojson加载…...
Python FastAPI + Celery + RabbitMQ 分布式图片水印处理系统
FastAPI 服务器Celery 任务队列RabbitMQ 作为消息代理定时任务处理 首先创建项目结构: c:\Users\Administrator\Desktop\meitu\ ├── app/ │ ├── __init__.py │ ├── main.py │ ├── celery_app.py │ ├── tasks.py │ └── config.py…...
阶段项目:Windows 服务器的组建与管理
项目概述 公司简介 创鑫公司是一家新成立的小型 IT 公司 公司决定组建部署一个小型的企业网络 员工人数不到20人 使用一台独立的 Windows 服务器提供各种网络服务 网络拓扑 设计需求 权限部分 权限部分要求 公司的网络管理员对办公计算机和服务器分别进行独立管理ÿ…...
【408】26考研-王道计算机408
王道408考研全套视频资料: 讲义01.26考研王道计算机【C语言督学营】02.【408领学班】26考研王道计算机B站独家03.26考研王道计算机【组成原理领学班】04.26王道计算机【计算机网络领学班】05.26考研王道计算机【数据结构领学班】06.26王道计算机【操作系统领学班】…...
数据分析问题思考路径
一、思考问题 1. 确认问题 因为背景: 因为5月1日的营业额突然下滑了10%,而历史从未出现过类似的跌幅 我想目的: 我想知道本次下滑的原因以此避免再出现这样的异常情况 现在思路: 现在能想到是原因是节假日和产品环节转化异常 最后感谢: 想请你帮我取数分析一下,…...
vue省市区懒加载,用el-cascader 新增和回显
el-cascader对于懒加载有支持方法,小难点在于回显的时候,由于懒加载第一次只有一层,所以要根据选中id数组一层层的加载。 子组件 <template><el-cascaderref"cascaderRef"v-model"selectedValue":props"…...
从零构建大语言模型全栈开发指南:第三部分:训练与优化技术-3.3.3领域适配案例:医疗文本分类与法律合同生成
👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 从零构建大语言模型全栈开发指南-第三部分:训练与优化技术-3.3.3 领域适配案例:医疗文本分类与法律合同生成1. 领域适配的核心挑战与解决方案2. 医疗文本分类:从通用到专业的跃迁2.1 医疗领域适配的技…...
Web网页内嵌 Adobe Pdf Reader 谷歌Chrome在线预览编辑PDF文档
随着数字化办公的普及,PDF文档已成为信息处理的核心载体,虽然桌面端有很多软件可以实现预览编辑PDF文档,而在线在线预览编辑PDF也日益成为一个难题。 作为网页内嵌本地程序的佼佼者——猿大师中间件,之前发布的猿大师办公助手&am…...
Python WebSockets 库详解:从基础到实战
1. 引言 WebSocket 是一种全双工、持久化的网络通信协议,适用于需要低延迟的应用,如实时聊天、股票行情推送、在线协作、多人游戏等。相比传统的 HTTP 轮询方式,WebSocket 减少了带宽开销,提高了实时性。 在 Python 中ÿ…...
php根据一个数组里面的元素顺序来排序另外一个数组的的顺序
根据arr2的顺序来排序arr $arr [[size_id > 9],[size_id > 1],[size_id > 1],[size_id > 6],[size_id > 6],[size_id > 8],];$arr2 [1,9,6,8];usort($arr, function ($item1, $item2) use ($arr2) {return array_search($item1[size_id], $arr2) - array_s…...