QEMU Machine Protocol(QMP)协议规范实战指南:从 JSON 消息格式到源码级实现解析
QEMU Machine ProtocolQMP协议规范实战指南从 JSON 消息格式到源码级实现解析【免费下载链接】qemuOfficial QEMU mirror. Please see https://www.qemu.org/contribute/ for how to submit changes to QEMU. Pull Requests are disabled. Please only use release tarballs from the QEMU website.项目地址: https://gitcode.com/gh_mirrors/qe/qemuQMPQEMU Machine Protocol是 QEMU 提供的基于 JSON 的机器级控制协议供上层应用如 libvirt、OpenStack 等管理工具以结构化方式驱动 QEMU 进程同时也被 QEMU Guest AgentQGA用于宿主机与客户机操作系统之间的交互。本文将基于仓库中的官方规范文档 docs/interop/qmp-spec.rst结合 QEMU 源码monitor 层、qapi 层与命令定义qapi/*.json系统讲解 QMP 的协议格式、能力协商、命令执行、响应结构、异步事件、OOB 带外执行、解析器复位、QGA 同步、兼容性约束与下游扩展规范帮助读者完整掌握 QMP 的协议细节并能够直接编写出符合规范的 QMP 客户端。QMP 协议总览QMP 是一个以换行符为边界、基于 JSON 文本行的请求/响应协议。它的定位是机器级machine-level接口与面向人机交互的 HMPHuman Monitor Protocol不同QMP 的所有消息都是结构化 JSON 对象便于程序化解析与自动化运维。根据 docs/interop/qmp-spec.rst该协议同时服务两类角色Server服务端QEMU 进程本身或 QEMU Guest AgentQGAClient客户端任何通过 QMP 与 Server 通信的应用程序。具体命令与数据结构的详细参考分别见 docs/interop/qemu-qmp-ref.rstQEMU QMP 参考与 qemu-ga-refQGA 参考本文聚焦协议本身的通用格式规范。协议的基本数据约定规范中提到的所有 JSON 数据结构均以如下形式表示json-DATA-STRUCTURE-NAME其中DATA-STRUCTURE-NAME是任意合法的 JSON 数据结构依据 JSON 标准 RFC 8259 定义。协议层的核心约定如下编码Server 期望输入为 UTF-8 编码输出为 ASCII 编码成员顺序文档中为了阅读方便会按固定顺序列出 json-object 的成员但真实协议中成员可以是任意顺序客户端不能假设任何特定顺序数组顺序json-array 的元素顺序默认是重要的除非另行说明客户端应保留数组顺序语义重复键在同一个 json-object 中重复出现同一个键会产生不可预测的结果属于未定义行为单引号扩展为方便起见Server 接受用单引号替代标准双引号的 json-string两种输入形式都额外理解转义序列\表示单引号。但 Server 在输出时只会使用双引号。消息的通用形态Server 发送的所有交互消息都是 json-object并且总是以 CRLF\r\n结尾。除非特别说明json-object 的所有成员都是必需的。连接建立Server Greeting服务端问候当客户端刚刚连接到 QMP 时Server 会立即发送一条问候消息greeting其作用有两点确认连接成功建立宣告 Server 已就绪可以进行能力协商见下文Capabilities Negotiation。问候消息格式{ QMP: { version: json-object, capabilities: json-array } }各成员含义versionServer 的版本信息格式与query-version命令的返回值一致包含qemu的三段式版本号major/minor/micro与package字段capabilities声明 Server 在基线规范之外支持的扩展能力数组内元素顺序无特定意义。从源码看问候消息由 monitor/qmp.c 中的qmp_greeting()生成它通过qmp_marshal_query_version()填充版本信息再遍历mon-capab_offered[]数组把 Server 支持的能力名如oob依次追加到cap_list中最终拼装为{QMP: {version: ..., capabilities: ...}}结构。也就是说greeting 中的 capabilities 列表是动态生成的只包含当前连接实际可用的能力。在 monitor/qmp.c 的monitor_qmp_caps_reset()中可以看到oob能力的提供与否取决于monitor_requires_iothread()的返回值——只有启用了 monitor I/O 线程如基于 iothread 的 chardev 后端时oob才会被列入 offered 能力。当前支持的能力目前规范定义的能力只有一个能力名说明oob支持带外Out-of-Band命令执行详见下文Out-of-band execution在 QAPI 定义层该能力对应的枚举类型QMPCapability定义于 qapi/control.json目前仅有oob一个取值。能力协商Capabilities Negotiation客户端建立连接后Server 处于Capabilities Negotiation能力协商模式。该模式有以下限制只允许执行qmp_capabilities命令其他任何命令都会返回CommandNotFound错误不投递任何异步事件消息。客户端应当通过qmp_capabilities命令显式开启 greeting 中已宣告且自身支持的能力。qmp_capabilities命令的行为在 qapi/control.json 中有完整定义其要点包括可选参数enable要启用的QMPCapability值列表客户端不得启用 greeting 中未提及的能力若省略该字段表示不启用任何能力since 2.12该命令仅在刚连接时有效必须在其他任何命令被接受之前发出一旦 monitor 开始接受其他命令再调用就会失败客户端需要显式开启能力否则所有 QMP 能力默认关闭。从源码实现看monitor/qmp-cmds-control.c 中的qmp_qmp_capabilities()先检查当前命令表若mon-commands已经是qmp_commands即协商已完成则返回COMMAND_NOT_FOUND错误Capabilities negotiation is already complete, command ignored否则调用qmp_caps_accept()校验所请求的能力是否在mon-capab_offered[]中若客户端请求了未提供的能力会返回形如Capability %s not available的错误见 monitor/qmp-cmds-control.c。协商成功后mon-commands被切换为qmp_commandsServer 进入Command 模式。进入 Command 模式后能力变更生效除qmp_capabilities外的所有命令均被允许执行异步事件开始正常投递。qmp_capabilities命令还带有allow-preconfig标记见 qapi/control.json意味着在 preconfig 阶段也可调用。另外monitor/qmp.c 的monitor_qmp_dispatch()中还做了一层兜底在协商模式下若收到非qmp_capabilities命令且返回了CommandNotFound会将其错误描述替换为更有指导意义的Expecting capabilities negotiation with qmp_capabilities。命令执行Issuing Commands命令执行请求有两种格式{ execute: json-string, arguments: json-object, id: json-value }或请求带外执行{ exec-oob: json-string, arguments: json-object, id: json-value }各成员含义execute/exec-oob标识要执行的命令名。exec-oob请求带外执行要求能力协商阶段已启用oobarguments命令所需的参数对象当命令不需要参数时可省略每个命令都文档化了它接受何种参数内容id事务标识可选。若提供则对应的响应消息中会原样带回该id便于请求与响应配对id可以是任意 JSON 值实践中推荐使用每次递增的 json-number。从源码看qapi/qmp-dispatch.c 中的qmp_dispatch_check_obj()负责对请求对象做结构性校验execute或启用了oob时的exec-oob必须是字符串arguments必须是对象id会被放行出现重复的execute/exec-oob键或未知键则报错。这印证了协议严格校验、宁严勿松的设计取向。Out-of-band 带外执行默认情况下Server顺序地读取、执行并响应命令客户端因此会按发出顺序收到响应。启用oob能力通过能力协商后行为发生变化Server 一边读取一边把命令排入队列再逐一从队列取出执行带外命令插队exec-oob命令会跳过队列中的在带命令被立即执行因此客户端可能先收到该命令的响应后收到先前在带命令的响应为把响应匹配回命令客户端必须为带外命令携带id规范建议接受oob能力的客户端为所有命令都携带id如果客户端发送在带命令的速度超过 Server 的执行速度Server 会暂停读取请求直到请求队列长度降到可接受范围为保证带外命令能被读取并执行客户端在途in-flight的在带命令最多不要超过 8 个只有少数命令支持带外执行判断标准是query-qmp-schema输出中该命令带有allow-oob: true。从源码看带外命令的插队路径在 monitor/qmp.c 的handle_qmp_command()中非常直观一旦检测到请求含exec-oob键qmp_is_oob(qdict)就立即调用monitor_qmp_dispatch()执行并返回根本不会进入在带命令的排队逻辑g_queue_push_tail(mon-qmp_requests, ...)。在带命令的队列上限由QMP_REQ_QUEUE_LEN_MAX控制见 monitor/qmp.c队列满时monitor_suspend()会挂起输入待 monitor/qmp.c 的monitor_qmp_dispatcher_co()协程消费后monitor_resume()恢复——这就是规范中暂停读取请求的底层实现。哪些命令支持 OOB查看 QAPI 定义即可例如迁移控制命令migrate-pause、migrate-continue定义在 qapi/migration.jsonyank 系列命令在 qapi/yank.json它们都显式标注了allow-oob: true。而allow-oob字段本身在 QAPI 内省结构中定义为布尔类型见 qapi/introspect.json。命令响应Commands Responses命令执行后 Server 会产生两类响应成功success或失败error。只要命令携带了id对应的响应消息中就会附带相同的id客户端应丢弃所有id未知的响应。成功响应格式{ return: json-value, id: json-value }return命令返回的数据具体内容按命令而定——通常是 json-object 或 json-array有时是 json-number、json-string若命令无返回数据则为空 json-object{}id若客户端发出时携带了事务标识则原样返回。错误响应格式{ error: { class: json-string, desc: json-string }, id: json-value }class错误类别名称例如GenericErrordesc人类可读的错误描述。客户端不应尝试解析该文本它不构成稳定接口id若客户端发出时携带了事务标识则原样返回。需要注意某些错误可能发生在 Server 尚未读取到id成员之前例如 JSON 解析失败此时即使客户端提供了id错误响应中也不包含id。带外执行中的响应乱序在启用oob后响应的到达顺序不再保证与请求发出顺序一致原因见上文因此客户端绝不能假设响应顺序必须以id为唯一的配对依据。异步事件Asynchronous Events由于状态变化Server 可能在任何时候只要不处于响应发送中间主动向客户端推送消息这类消息称为异步事件。格式{ event: json-string, data: json-object, timestamp: { seconds: json-number, microseconds: json-number } }各成员含义event事件名称data事件专属数据按事件定义可选timestamp事件在 Server 侧发生的精确时间是固定结构的 json-objectseconds和microseconds表示相对 Unix Epoch1970-01-01的时间若获取宿主机时间失败两个成员都会被置为-1。事件的具体清单见 docs/interop/qemu-qmp-ref.rst如POWERDOWN、RESET、SHUTDOWN、DEVICE_DELETED等。此外规范还说明部分事件被限速为每秒至多一条若一秒钟内到达多条相似事件除最后一条外其余全部丢弃且最后一条会被延迟投递相似通常指事件类型相同。该机制用于防止事件洪泛压垮客户端。值得注意的是在能力协商模式下异步事件不会被投递见上文Capabilities Negotiation源码对应实现是 monitor/qmp.c 的monitor_qmp_emit_event()若qmp-commands qmp_cap_negotiation_commands则直接返回不发送任何事件。将 JSON 解析器恢复到已知良好状态不完整或非法的输入可能让 Server 的 JSON 解析器陷入无法继续解析后续命令的状态。恢复方法是人为制造一个词法错误lexical error最干净的做法是发送一个 ASCII 控制字符——但不能是\t水平制表符、\r回车、\n换行。如果客户端需要兼容老版本 QEMU它们可能无法把普通控制字符标记为错误则应改发一个0xFF 字节。QGA 同步QGA Synchronization当客户端通过不具备完善连接语义的传输通道如 virtio-serial连接 QGA 时QGA 可能已经读取了上一个客户端遗留的部分输入。此时客户端需要使用上一节解析器恢复到已知良好状态的方法强制 QGA 的解析器进入已知良好状态客户端还可能收到上一个客户端未读走的输出。为跳过这些残留输出QGA 提供了guest-sync-delimited命令详见 QGA 参考文档 qemu-ga-ref。QMP 实战示例规范给出了完整的真实交互示例其中-表示客户端发送-表示 Server 回复。示例 1Server greeting- { QMP: {version: {qemu: {micro: 0, minor: 0, major: 3}, package: v3.0.0}, capabilities: [oob] } }示例 2能力协商- { execute: qmp_capabilities, arguments: { enable: [oob] } } - { return: {}}示例 3简单执行stop命令- { execute: stop } - { return: {} }示例 4查询 KVM 信息带 id- { execute: query-kvm, id: example } - { return: { enabled: true, present: true }, id: example}示例 5解析错误- { execute: } - { error: { class: GenericError, desc: JSON parse error, expecting value } }示例 6Powerdown 事件- { timestamp: { seconds: 1258551470, microseconds: 802384 }, event: POWERDOWN }示例 7带外执行错误场景- { exec-oob: migrate-pause, id: 42 } - { id: 42, error: { class: GenericError, desc: migrate-pause is currently only supported during postcopy-active state } }可以看到解析错误示例 5由于发生在读取id之前错误响应中没有id而带外命令示例 7是合法 JSONid被原样带回。这正对应前文关于错误响应中id是否存在的说明。兼容性考虑Compatibility Considerations协议在演进过程中保持严格的向后兼容策略不兼容的协议改动默认关闭并通过 greeting 中的 capabilities 数组宣告客户端检查该数组后只启用自己支持的能力QMP Server 对命令参数执行类型检查若某个值与其键的期望类型不符或客户端包含 Server 无法识别的键会生成错误这种严格性可以及早暴露客户端对 Server schema 的错误假设。客户端可以假定这类校验错误发生在命令产生任何副作用之前即校验失败不会留下半执行状态。但客户端不得假设以下任何一点json-array 的长度json-object 的大小——特别是未来版本可能新增键客户端应能忽略未知键json-object 成员或 json-array 元素的顺序命令可能产生的错误数量——新版本 Server 可能给任何既有命令增加新错误。此外任何以x-开头的命令或成员名都被视为实验性的未来版本可能以不兼容方式被移除或修改。最后Server 只保证输出合法 JSON除此之外客户端应遵循发送时保守接收时宽容conservative in what they send, and liberal in what they accept的原则。下游扩展 QMPDownstream Extension of QMP官方建议下游消费者downstream不要修改 QMP以便管理工具无需特殊逻辑即可同时支持上游与下游版本。但既然现实中有不可避免的修改需求规范给出了明确的互操作约定保留命名空间__前缀QMP 为下游保留了以__双下划线开头的 JSON 对象成员名downstream names。上游永远不会用这些名字命名命令、参数、错误或异步事件。下游新增的任何名字都必须以__开头为保证与其他下游的兼容性强烈建议再追加__RFQDN_前缀RFQDN 是你拥有且合法的反向完全限定域名。例如 qemu-kvm 专属的 monitor 命令(qemu) __org.linux-kvm_enable_irqchip下游行为约束除提供额外能力外不得改动 server greeting但规范也指出连新增能力都不被鼓励见下上一节兼容性考虑对下游同样适用对于不含下游成员的输入下游必须表现得与上游完全一致唯一的例外是它可以在输出中添加带下游名字的成员因此只要客户端不发送含下游成员的输入、并能正确忽略收到的下游成员就不应该能区分出上游与下游。关于下游修改的官方建议新增命令是允许的若想扩展现有命令考虑用带新行为的新命令替代新增异步消息是允许的若想扩展现有消息考虑新增一条消息而非修改为新命令引入新错误是允许的但给现有命令添加新错误属于扩展行为应按第 1 条处理即改用新命令新增能力被强烈劝阻能力用于演进基础协议本身多个分叉的基础协议方言是最不受欢迎的结局。从源码理解 QMP 的完整生命周期综合以上规范与源码一个典型 QMP 会话的完整流程可以总结为连接客户端建立 TCP如-qmp tcp:localhost:4444,serveron,waitoff或 unix socket 连接GreetingServer 在CHR_EVENT_OPENED时见 monitor/qmp.c把命令表切到qmp_cap_negotiation_commands、复位能力并发送 greeting能力协商客户端发送qmp_capabilities可带enable: [oob]成功后进入 Command 模式monitor/qmp-cmds-control.c命令执行客户端发送{ execute: ... }请求经 JSON 解析json_message_parser_feed见 monitor/qmp.c、结构性校验qapi/qmp-dispatch.c、分发执行后通过qmp_send_response()返回结果monitor/qmp.c异步事件状态变化触发monitor_qmp_emit_event()主动推送仅在 Command 模式断开CHR_EVENT_CLOSED时清理请求队列、重建解析器monitor/qmp.c。对于想要进一步深入源码的读者以下文件是核心入口协议规范 docs/interop/qmp-spec.rst命令与内省参考 docs/interop/qemu-qmp-ref.rstQMP 主实现 monitor/qmp.c控制类命令实现 monitor/qmp-cmds-control.c分发与校验核心 qapi/qmp-dispatch.c控制类命令与能力枚举的 QAPI 定义 qapi/control.jsonOOB 相关命令定义allow-oob: true qapi/migration.json、qapi/yank.json内省结构中allow-oob字段 qapi/introspect.json掌握以上协议格式与源码路径后开发者既可以直接手工编写 QMP 客户端脚本如用 Python 的socket连接并收发 JSON也可以在此基础上理解 libvirt、OpenStack 等上层管理栈如何通过 QMP 驱动 QEMU为诊断问题、定制管理工具或做下游集成打下坚实基础。【免费下载链接】qemuOfficial QEMU mirror. Please see https://www.qemu.org/contribute/ for how to submit changes to QEMU. Pull Requests are disabled. Please only use release tarballs from the QEMU website.项目地址: https://gitcode.com/gh_mirrors/qe/qemu创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

基于文本的MBTI人格预测:从TF-IDF到FastAPI服务部署

基于文本的MBTI人格预测:从TF-IDF到FastAPI服务部署

简介:这份资源是一套基于机器学习的MBTI人格预测系统完整项目,面向具备一定Python基础、希望将机器学习落地到文本与行为分析场景的开发者与学习者。项目围绕个体语言和行为模式展开,涵盖数据清洗、特征分析处理、人格预测模型构建、参数调优…

2026/9/24 2:19:05 阅读更多 →
项目管理资源管理思维导图与实战技巧

项目管理资源管理思维导图与实战技巧

1. 项目资源管理全景图在项目管理领域,资源管理就像乐高积木的底板,所有其他知识领域都要在这个基础上搭建。我做了15年项目经理,见过太多因为资源管理不善导致项目崩盘的案例。最近整理了一套可视化思维导图,把PMBOK第六版第13章…

2026/9/23 1:14:09 阅读更多 →
微电网中T型三电平逆变器的VSG与PQ协同控制策略

微电网中T型三电平逆变器的VSG与PQ协同控制策略

1. 项目背景与核心价值微电网作为分布式能源系统的关键载体,正在重塑传统电力供应模式。这个项目聚焦于采用两台T型三电平逆变器构建的局域微电网系统,通过VSG(虚拟同步发电机)和PQ(有功-无功)控制策略的协…

2026/9/24 1:33:06 阅读更多 →

最新新闻

CVE-2025-27591深度解析:日志组件本地权限提升漏洞与防御

CVE-2025-27591深度解析:日志组件本地权限提升漏洞与防御

CVE-2025-27591 最近在安全圈里讨论度不低,核心是 Below 这个日志处理组件在权限控制上出了问题,低权限用户有机会利用日志文件、临时目录的处理流程,把自身权限抬升到管理员甚至系统级别。很多人一听到“利用脚本”就先想到怎么打&#xff0…

2026/9/24 23:59:40 阅读更多 →
Minke+DeepSeek Harness:搭建本地优先的智能体工作台

Minke+DeepSeek Harness:搭建本地优先的智能体工作台

Minke 这名字最近在本地 AI 玩家里传得挺快,尤其是搭配“本地优先”这四个字,基本戳中了不少人的痛点。我也跟风折腾了一段时间,把它和 DeepSeek 的 Harness 插件组合在一起,当作日常桌面端的主力智能体工作台来用。这篇东西不搞虚…

2026/9/24 23:59:40 阅读更多 →
监控立杆基础施工工艺标准:从设计参数到验收避坑全解析

监控立杆基础施工工艺标准:从设计参数到验收避坑全解析

简介:监控立杆基础施工工艺标准面向安防与道路监控工程的施工人员、现场工程师和验收人员,用于规范立杆选材、热浸镀锌、基础浇注、防雷接地及质量检验等全过程。资源为单个doc文件,压缩包仅34KB,内容紧凑实用,可作为施…

2026/9/24 23:59:40 阅读更多 →
微型电动汽车后悬架设计全流程:从计算到建模的避坑指南

微型电动汽车后悬架设计全流程:从计算到建模的避坑指南

简介:面向新能源汽车与汽车工程领域的学术设计参考,这份 PDF 以两座微型电动汽车后悬架为研究对象,完整呈现悬架系统选型到参数计算的设计思路。资源为 1 个 PDF 文档,压缩包大小约 2.79MB,目前已有 122 人学习下载。文…

2026/9/24 23:59:40 阅读更多 →
苍穹外卖day05--Redis配置以及应用

苍穹外卖day05--Redis配置以及应用

苍穹外卖day05–Redis配置以及应用 文章目录苍穹外卖day05--Redis配置以及应用前言Redis简介Redis环境配置店铺营业状态设置总结前言 第五天简单的介绍了一下Redis以及在苍穹外卖中的应用。 Redis简介 我们先说熟悉的MySQL,MySQL是通过数据文件将数据存储到硬盘上…

2026/9/24 23:59:40 阅读更多 →
SpaceX-API 单颗 Starlink 卫星查询接口详解:GET /v4/starlink/:id 的请求、响应与底层实现

SpaceX-API 单颗 Starlink 卫星查询接口详解:GET /v4/starlink/:id 的请求、响应与底层实现

后端API设计 【免费下载链接】SpaceX-API :rocket: Open Source REST API for SpaceX launch, rocket, core, capsule, starlink, launchpad, and landing pad data. 项目地址: https://gitcode.com/gh_mirrors/spa/SpaceX-API 点击查看 免费下载 本篇技术指南以 S…

2026/9/24 23:58:40 阅读更多 →

日新闻

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/24 14:34:13 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/24 9:10:42 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/24 14:33:56 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/24 12:50:34 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/24 14:33:48 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/24 12:49:17 阅读更多 →