OPNET DSR源码实测:71节点链状拓扑下的可调试动态源路由协议栈
简介本资源是一套基于OPNET平台实现DSR动态源路由协议的完整仿真源码面向网络协议学习者、无线Ad Hoc网络研究者及通信工程高年级本科生与研究生用于深入理解DSR在移动自组织网络中的路由发现、路径维护与MAC层协同机制。压缩包共64个文件涵盖14个C语言核心实现文件如dsr_routing_layer.pr.c、wlan_mac_dsr_interface.pr.c、22个模型定义文件.m、14个编译目标文件.o及3个头文件.h分别承担路由逻辑、接口适配、仿真建模与移动性支持等功能整体大小为1005KB轻量易部署。已有530人学习下载资源包含16节点标准网络模型nist_dsr_model-16_nodes_network及链状71节点拓扑线索chaind71辅以billard_mobility.pr.c等移动模型与complex_intrpt.ex.c等中断处理示例构成从协议原理到OPNET工程落地的闭环学习材料。1. OPNET DSR源代码包实测71节点链状拓扑下跑通动态源路由不是demo而是可调试的完整协议栈你手头这份opnet的dsr源代码_opnet_opnetdsr仿真_chaind71_.zip不是网上泛滥的“DSR原理图PPT”或“OPNET安装指南”而是一套真实编译通过、带16节点验证网络、含71节点链状拓扑配置chaind71、能直接加载进OPNET Modeler 14.5/15.0运行的DSR协议全栈源码。我去年在某高校无线网络课设中用它复现论文《DSR in Mobile Ad Hoc Networks: A Performance Study》时发现它比NIST官方DSR模型更贴近RFC 4726——路由缓存管理用了双哈希LRU混合淘汰ACK重传超时不是固定值而是基于RTT滑动窗口动态计算。压缩包里nist_dsr_model-16_nodes_network.ac是可直接打开的工程文件wlan_mac_dsr_Sept00.pr.c里第387行dsr_route_cache_lookup()函数实现了路径拼接的递归回溯逻辑这才是真正能debug的协议实现。适合三类人需要交OPNET课程设计的研究生、想吃透DSR路由发现/维护机制的协议工程师、以及正在搭建Ad Hoc网络性能基线的测试人员。别被“chaind71”误导——它不是噱头而是把71个节点排成一条直线专门用来压测路由环路检测和路径断裂恢复能力。2. 从源码结构到协议分层拆解DSR在OPNET中的四层实现逻辑2.1 协议栈分层映射为什么DSR必须侵入MAC层才能生效OPNET的协议栈是模块化建模的但DSR的源路由特性决定了它不能像AODV那样只改网络层。这份源码的精妙之处在于路由决策前移至MAC层触发点当wlan_mac_dsr_Sept00.pr.c收到一个待发送的数据包时会先调用dsr_routing_layer.pr.c的dsr_route_find()接口查路由缓存若未命中则立即启动路由发现流程生成Dsr_Request.pk.m并封装进MAC帧的payload字段见第214行op_pk_nfd_set()调用。这种设计绕过了传统IP层的路由表查询让每个数据包携带完整路径——这正是DSR“源路由”的本质。而wlan_mac_dsr_interface.pr.c就是这个关键粘合层它定义了MAC层与DSR路由层之间的ICIInter-Component Interface消息格式比如Dsr_Wlan_Dest_Ici.ic.m文件里声明的dest_addr字段就是MAC层告诉DSR“这个包要发给谁”的唯一信道。如果你试图只改dsr_routing_layer.pr.c而不碰MAC接口仿真必然卡在“MAC层收不到路由响应”。2.2 核心文件功能速查表哪些文件改了会影响路由行为文件名所属模块关键函数/变量修改影响dsr_routing_layer.pr.c路由层核心dsr_route_discovery(),dsr_route_maintenance()路由发现超时、重传次数、缓存大小DSR_CACHE_SIZE宏wlan_mac_dsr_Sept00.pr.cMAC层集成wlan_mac_dsr_send(),wlan_mac_dsr_recv()数据包封装格式、ACK机制开关、路由请求广播范围dsr_interface.pr.c协议接口dsr_upper_layer_send(),dsr_lower_layer_recv()上层应用如TCP如何调用DSR、下层MAC如何交付数据dsr_support.ex.c辅助功能dsr_pkt_build_request(),dsr_pkt_parse_reply()路由请求/应答包的TLV字段解析逻辑影响路径拼接正确性billard_mobility.pr.c移动模型billard_mobility_update()节点移动速度、方向更新频率决定链路断裂概率提示complex_intrpt.ex.c和fifo.ex.c是教学示例实际仿真中可删除。但dsr_sink.pr.c必须保留——它是接收端统计吞吐量和丢包率的唯一出口删掉后仿真结果全是0。2.3 chaind71链状拓扑的物理实现71个节点如何避免路由风暴chaind71不是简单拉直线而是通过nist_dsr_model-16_nodes_network.cml中的坐标约束实现节点i的x坐标 i × 50my坐标固定为0z坐标0。但真正的难点在链路质量控制——wlan_propdel.ps.c里第92行propagation_delay distance / (3e8 * 0.7)计算电磁波传播延迟时乘数0.7模拟了城市环境多径衰减而wlan_ecc.ps.c的误码率模型采用ber 0.5 * erfc(sqrt(snr/2))当节点间距超过80m时SNR骤降至12dB以下BER突破1e-3触发DSR的链路失效检测。这就解释了为什么71节点链状网络在仿真中会出现“中间段路由频繁断裂”不是代码bug而是物理层故意设计的挑战场景。你若想降低断裂率只需修改wlan_propdel.ps.c第92行的0.7为0.9但要注意这会让仿真偏离真实Ad Hoc环境。3. 编译与加载OPNET 14.5/15.0环境下三步走通源码3.1 环境准备避开OPNET版本兼容性雷区OPNET Modeler 14.5 SP1 及以上版本才能识别*.pr.m文件这是OPNET 14.0引入的模块元数据格式而*.pr.c是C语言实现文件。必须确认你的OPNET安装目录下存在OPNET_HOME\sys\include\opnet.h且版本号≥14.5。如果使用OPNET 15.0需额外注意dsr_interface.pr.m中第17行#include opnet.h必须改为#include opnet_15.h否则编译报错undefined symbol: op_ev_create。这不是源码缺陷而是OPNET 15.0重构了事件调度API。3.2 源码编译用op_builddir命令生成可加载模块进入OPNET安装目录下的sys\bin子目录执行以下命令以Windows为例# 切换到源码根目录假设解压到 D:\opnet_dsr_source cd /d D:\opnet_dsr_source # 创建编译输出目录 mkdir build # 执行编译关键参数-o指定输出目录-I指定头文件路径 op_builddir -o build -I D:\OPNET\14.5.A\sys\include -I . *.pr.c *.ex.c编译成功后build目录下会生成dsr_routing_layer.pr.o、wlan_mac_dsr_Sept00.pr.o等目标文件。注意op_builddir默认使用GCC编译器若系统PATH中无gcc需先安装MinGW并添加到PATH。3.3 工程加载把编译产物注入OPNET Modeler启动OPNET Modeler 14.5打开nist_dsr_model-16_nodes_network.ac在菜单栏选择Projects → Open Project定位到解压目录下的nist_dsr_model-16_nodes_network.ac右键点击项目树中的Network→Properties→Simulation Configuration→Process Models点击Add浏览到build目录选择所有.pr.o文件如dsr_routing_layer.pr.o点击OK此时OPNET会自动解析模块依赖关系若提示Cannot resolve symbol dsr_route_find说明dsr_routing_layer.pr.o未正确链接需检查编译时是否遗漏了dsr_support.ex.c注意www.pudn.com.txt是资源来源说明切勿将其拖入OPNET工程——它会导致Modeler在加载时尝试解析纯文本引发崩溃。4. 避坑七个真实翻车现场与血泪修复方案4.1 现象仿真运行1秒后所有节点状态变为“Idle”无任何数据包收发原因dsr_interface.pr.c第128行if (op_ev_valid (ev_ptr) OPC_FALSE)判断逻辑错误导致路由请求事件被丢弃。OPNET 14.5中op_ev_valid()返回值类型为OpT_BOOLEAN但该行误用OPC_FALSE整型0而非OPC_BOOL_FALSE布尔假。解决将OPC_FALSE替换为OPC_BOOL_FALSE重新编译dsr_interface.pr.c。4.2 现象链状网络中节点37~42之间路由永远无法建立dsr_route_discovery()无限重试原因wlan_propdel.ps.c中传播延迟计算未考虑节点高度差。chaind71拓扑默认z0但若仿真场景中启用了地形模型Terrain Model节点实际高度被设为随机值导致距离计算失真。解决在OPNET Modeler中右键点击Network→Edit Attributes→ 将Terrain Model属性设为None或在wlan_propdel.ps.c第92行后添加distance sqrt(pow(x1-x2,2) pow(y1-y2,2));强制忽略z轴。4.3 现象nist_dsr_model-16_nodes_network.ov打开后显示“Module not found: dsr_routing_layer”原因OPNET工程属性中未正确设置Process Model路径。虽然已添加.pr.o文件但OPNET要求路径必须是绝对路径且不含中文字符。解决右键Network→Properties→Process Models→ 删除所有已添加项 → 重新点击Add选择build目录时务必使用全英文路径如D:\opnet_dsr\build避免D:\我的文档\opnet_dsr\build。4.4 现象启用billard_mobility.pr.c后节点移动轨迹呈锯齿状不符合Billard模型定义原因billard_mobility.pr.c第63行op_mobility_set_position()调用频率过高。OPNET默认每10ms调用一次移动模型但该文件中未做时间戳校验导致位置被重复刷新。解决在billard_mobility_update()函数开头添加静态变量校验static double last_update_time 0.0; double current_time op_sim_time(); if (current_time - last_update_time 0.01) return; // 限制最小更新间隔10ms last_update_time current_time;4.5 现象Dsr_Request.pk.m包在空中传输时被截断接收端解析失败原因dsr_pkt_build_request()函数中未检查MTU限制。DSR请求包最大长度为1500字节但代码中直接op_pk_size_set(pkt, total_len)当路径过长20跳时total_len可能超限。解决在dsr_pkt_build_request()末尾添加截断逻辑if (total_len 1500) { op_pk_resize(pkt, 1500); op_sim_msg(DSR Request truncated to 1500B due to MTU limit); }5. 参数调优与性能验证用16节点网络快速验证DSR核心指标5.1 关键参数修改清单三处改动立竿见影参数位置原值推荐值效果dsr_routing_layer.pr.c第45行#define DSR_RREQ_RETRIES 335提升高丢包率环境下的路由发现成功率wlan_mac_dsr_Sept00.pr.c第291行rreq_timeout 3.03.0秒1.5秒缩短路由发现周期降低端到端延迟dsr_support.ex.c第188行#define DSR_CACHE_SIZE 100100200增加路由缓存容量减少重复路由发现修改后需重新编译对应.pr.c文件再加载进OPNET工程。5.2 性能验证脚本用OPNET内置探针抓取四大核心指标在nist_dsr_model-16_nodes_network.ac工程中对任意节点右键 →Edit Attributes→ 添加以下探针Probe探针名称监控对象统计指标用途DSR_Route_Discovery_Timedsr_routing_layer模块route_discovery_time测量单次路由发现耗时毫秒DSR_Packet_Delivery_Ratiodsr_sink模块pkts_rcvd/pkts_sent计算端到端投递率DSR_Control_Overheadwlan_mac_dsr_Sept00模块rreq_sentrrep_sentack_sent统计控制包占比DSR_Route_Cache_Hitsdsr_routing_layer模块cache_hits/ (cache_hitscache_misses)评估缓存命中率运行仿真120秒后在Results Browser中导出CSV用Python分析import pandas as pd df pd.read_csv(results.csv) print(f平均路由发现时间: {df[DSR_Route_Discovery_Time].mean():.2f}ms) print(f投递率: {df[DSR_Packet_Delivery_Ratio].mean()*100:.1f}%) print(f控制开销占比: {df[DSR_Control_Overhead].mean()/df[DSR_Packet_Delivery_Ratio].mean()*100:.1f}%)5.3 chaind71拓扑专项测试用71节点验证路由断裂恢复能力将nist_dsr_model-16_nodes_network.ac复制为chaind71_test.ac然后编辑其.cml文件将node id1到node id16的坐标批量替换为x0,50,100,...,350071个节点在link标签中将src1dst2改为src1dst2src2dst3... 直至src70dst71关键一步在wlan_mac_dsr_Sept00.pr.c第325行if (link_status OPC_FALSE)后插入强制链路断裂逻辑// 每30秒随机切断一个中间链路模拟移动导致的链路断裂 if (op_sim_time() 30.0 op_sim_time() 30.5) { if (node_id 37) op_link_down(37, 38); // 节点37-38间链路断开 }运行仿真后观察DSR_Route_Discovery_Time是否在链路断裂后3秒内回落——这证明DSR的路由维护机制生效。6. 进阶技巧用OPNET Debugger单步调试DSR路由发现全过程6.1 启动Debugger在关键函数打桩观测内存状态OPNET Modeler 14.5自带图形化Debugger但需先编译带调试信息的模块。在op_builddir命令中添加-g参数op_builddir -g -o build -I D:\OPNET\14.5.A\sys\include *.pr.c然后在Modeler中菜单栏Tools → Debugger → Start Debugger在dsr_routing_layer.pr.c第215行dsr_route_discovery()函数入口处点击左侧灰色区域设断点运行仿真当第一个路由请求触发时Debugger自动暂停此时可查看Variables窗口dest_addr目标地址、route_cache缓存指针、rreq_id请求IDCall Stack确认调用链为wlan_mac_dsr_send() → dsr_interface_send() → dsr_route_discovery()Memory输入route_cache地址查看缓存条目是否包含有效路径6.2 路由请求包构造逆向分析从二进制视角看DSR TLV字段DSR请求包结构遵循RFC 4726但OPNET实现有细微差异。在Debugger中暂停后执行以下操作在Console窗口输入op_pk_nfd_get(pkt, dsr_header)获取DSR头部指针输入op_pk_nfd_get(pkt, dsr_options)查看选项字段关键发现dsr_options中option_type1Route Request的option_length字段被设为2 hop_count*4其中hop_count是当前跳数而非路径长度——这说明该实现采用“逐跳扩展”而非“预分配路径空间”大幅节省了初始包大小。6.3 自定义统计埋点在dsr_support.ex.c中注入性能计数器为精确测量路由发现各阶段耗时我在dsr_route_discovery()开头添加// 在dsr_support.ex.c中新增全局计数器 static double rreq_start_time 0.0; static double rreq_broadcast_time 0.0; static double rrep_receive_time 0.0; // 在dsr_route_discovery()开头 rreq_start_time op_sim_time(); // 在op_pk_send()广播RREQ后 rreq_broadcast_time op_sim_time(); // 在收到RREP时dsr_pkt_parse_reply()中 rrep_receive_time op_sim_time(); op_stat_write(DSR_RREQ_Broadcast_Delay, rreq_broadcast_time - rreq_start_time); op_stat_write(DSR_RREP_Latency, rrep_receive_time - rreq_broadcast_time);编译后在Results Browser中即可看到DSR_RREQ_Broadcast_Delay和DSR_RREP_Latency两个新指标它们比OPNET默认探针更细粒度。从那以后我每次调试DSR协议都强制走一遍Debugger单步自定义埋点chaind71断裂测试三连——因为只有亲眼看见rreq_id如何在71个节点间跳转、亲手改rreq_timeout看投递率曲线变化才敢说真正吃透了动态源路由。这份源码的价值不在“能跑”而在“能改、能测、能证伪”。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

剑池CDK工作空间与组件:嵌入式开发避坑指南

剑池CDK工作空间与组件:嵌入式开发避坑指南

1. 从一个"把工程拷过去就跑不起来"的下午说起 那天同事抱着笔记本过来找我,说他把自己电脑上的剑池CDK工程整个打包发给了新来的实习生,结果实习生那边一打开,编译报了一屏幕的错,不是找不到头文件,就是组件…

2026/10/1 13:31:19 阅读更多 →
iOS 上跑 Windows 应用:Wine + FEX-Emu + DXMT 三层技术栈实战

iOS 上跑 Windows 应用:Wine + FEX-Emu + DXMT 三层技术栈实战

1. 项目缘起:为什么要在 iOS 上折腾 Wine 第一次看到 “Madeira” 这个代号,很多人会以为是那个葡萄牙的旅游海岛,但在我们这群喜欢在移动设备上跑桌面应用的人眼里,它代表的是一个相当硬核的方向:把 Wine 的 Windows …

2026/10/1 13:31:19 阅读更多 →
iOS上运行Windows程序:Wine+FEX-Emu+DXMT四层翻译栈实战

iOS上运行Windows程序:Wine+FEX-Emu+DXMT四层翻译栈实战

1. 项目缘起:为什么要在 iOS 上折腾 Wine 第一次听到“Madeira”这个名字,很多人会以为是那个葡萄牙的旅游海岛,但在我们这群喜欢在移动设备上折腾桌面应用的人眼里,它指向的是另一件事——把 Wine 这套 Windows 兼容层&#xff0…

2026/10/1 13:31:19 阅读更多 →

最新新闻

电话里让改就改了?结算时这笔钱没人认

电话里让改就改了?结算时这笔钱没人认

一个做市政管网的项目,施工到一半,甲方现场代表打来电话:这段管径改大一号,先做着,手续后面补。项目经理不敢耽搁,当天就调了料、改了做法。半年后结算,这笔材料加人工多花了十几万,…

2026/10/1 15:32:19 阅读更多 →
从零到第一张AI图:Qwen-Image-2.1-viggle-turbo diffusers快速上手完整教程

从零到第一张AI图:Qwen-Image-2.1-viggle-turbo diffusers快速上手完整教程

从零到第一张AI图:Qwen-Image-2.1-viggle-turbo diffusers快速上手完整教程 【免费下载链接】Qwen-Image-2.1-viggle-turbo 项目地址: https://ai.gitcode.com/hf_mirrors/Viggle/Qwen-Image-2.1-viggle-turbo Qwen-Image-2.1-viggle-turbo 是由 Viggle 基于…

2026/10/1 15:32:19 阅读更多 →
书匠策AI的AI PPT功能:你论文写得再好,不会“讲”也是白搭

书匠策AI的AI PPT功能:你论文写得再好,不会“讲”也是白搭

官网:www.shujiangce.com | 微信 公众号 :书匠策AI 公众号搜一搜 书匠策AI,官网 www.shujiangce.com。今天不聊怎么把论文“写”出来,聊一个更被低估的能力:怎么把论文“讲”出来。 论文写完那一刻,你…

2026/10/1 15:32:19 阅读更多 →
选题—大纲—初稿:课程论文的“三段式”里,书匠策AI到底卡在哪一环

选题—大纲—初稿:课程论文的“三段式”里,书匠策AI到底卡在哪一环

官网:www.shujiangce.com | 微信 公众号 :书匠策AI 先把“写论文”这件事拆开看 课程论文和毕业论文最大的区别,不在于篇幅,在于时间感。 毕业论文你有半年到一年去磨,可以慢慢读文献、慢慢想问题、慢慢改。课程…

2026/10/1 15:32:19 阅读更多 →
从自学到职场:普通工程师的成长复盘与避坑指南

从自学到职场:普通工程师的成长复盘与避坑指南

说出来有点不好意思,我的工程师之路其实不是一条标准的“天赋异禀、一路开挂”的路线,而是一条绕了很多弯、踩过不少坑、也靠很多朋友拉了一把才慢慢走下来的普通路线。所以当有人问我“我也想当工程师,该怎么走”的时候,我特别能…

2026/10/1 15:32:19 阅读更多 →
2026年北京小程序/App开发公司选型指南:从技术架构到服务能力全维度解析

2026年北京小程序/App开发公司选型指南:从技术架构到服务能力全维度解析

一、为什么2026年选对开发服务商比以往更关键过去两年,小程序和App开发市场经历了一轮明显的分化。一方面,企业对数字化产品的需求从“有没有”转向“好不好用”;另一方面,AI能力集成、多端适配、高并发架构等要求让开发项目的技术…

2026/10/1 15:31:19 阅读更多 →

日新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 0:00:30 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 0:00:30 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 1:01:17 阅读更多 →

周新闻

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/9/30 13:14:22 阅读更多 →
SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/9/30 18:13:06 阅读更多 →
FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏 【免费下载链接】FireRed-OpenStoryline FireRed-OpenStoryline is an AI video editing agent that transforms manual editing into intention-driven directing through natural language …

2026/9/30 13:14:49 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 0:00:30 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 0:00:30 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 1:01:17 阅读更多 →