从RDT到Reno:TCP可靠传输与拥塞控制实验全解析
简介计算机网络实验报告以TCP协议迭代开发为主线面向计算机网络课程实验与大作业场景适合正在学习传输层协议或需要完成类似实验的高校学生。报告完整记录了RDT 2.0、RDT 2.2、RDT 3.0、选择重传协议以及Reno拥塞控制五种机制的实现过程从前期的错误检测与ACK校验到超时重发、选择应答再到慢开始、拥塞避免、快恢复与乘法减小等策略均配有代码思路与LOG文件分析。针对LOG文件无法直接观察cwnd变化的难点报告给出了在每个传输轮次后输出发送包序号、接收包序号及当前cwnd值的解决方案并总结了迭代开发的优缺点与实验系统改进建议。资源压缩包仅含1个doc文档约945KB内容紧凑兼具原理说明、问题排查与经验反思。目前已有291人学习下载可作为TCP协议实验报告的优质参考帮助读者深入理解拥塞控制的动态过程和传输层工作原理。1. 从 RDT 2.0 到 Reno 拥塞控制这份 TCP 实验报告能帮你打通什么刚接触计算机网络大作业的人最容易卡在一个问题上教材里把可靠数据传输、滑动窗口、拥塞控制拆成好几章讲每章都懂合在一起就不知道代码该怎么写了。这份计算机网络实验报告走的是一条很经典的路线——从 RDT 2.0 开始一步步把位错、ACK 损坏、丢包、乱序、拥塞全加回去最终落到 Reno 拥塞控制的 cwnd 曲线。它本质上就是《计算机网络自顶向下》里可靠数据传输章节的工程化落地每加一个信道故障log 里就多一类记录你盯着日志就能看到协议行为的变化。适合正在写传输层大作业的人拿来对照结构也适合想搞懂「慢开始和拥塞避免到底在 log 里长什么样」的读者直接照着复现。2. 可靠传输的三次迭代位错、ACK 损坏与超时重发的 log 判读2.1 RDT 2.0 的发送端循环校验和与确认号队列RDT 2.0 解决的是「信道上可能出现位错」的问题。接收端对收到的每一个包都要重新计算校验和跟包里的校验字段比对不一致就认为出错、不返回 ACK发送端则循环检查确认号队列看有没有新收到的 ACK。这里有个容易被忽略的细节发送端不是在「收到 ACK 之后」才继续发而是在一个 while 循环里不断轮询确认号队列。我当年第一次写的时候把 ACK 处理写成了一个阻塞等待函数结果发送端一次只能发一个包整个实验的吞吐量直接变成停等协议的水平后来才意识到轮询才是这个版本的灵魂。发送端主循环常见的写法是这样伪代码如下# RDT 2.0 发送端主循环伪代码 seq 0 # 当前发送序号 while True: if have_data_to_send(): pkt make_pkt(seq, data, checksum(data)) # 计算校验和 udt_send(pkt) # 发送到信道 seq 1 - seq # 序号翻转 ack check_ack_queue() # 非阻塞检查确认号队列 if ack is not None and ack.seq last_send_seq: # 确认号与当前发送序号匹配说明对端收到了 mark_delivered(ack)这段逻辑里最关键的是check_ack_queue()。它不是recv()那样阻塞等待而是每轮循环都去看一眼队列里有没有新 ACK。这样设计的目的是让发送端在等待 ACK 期间还能继续干别的事比如超时计时、下一轮的数据准备。确认号队列本身保存的是接收端返回的原始 ACK 包发送端拿到之后要先比对ack.seq确认它回应的是当前这一号包。参数上最容易踩的是校验和的位数。实验框架里校验和通常用 16 位反码和也就是把数据按 16 位切块相加、溢出回卷、最后取反。如果你用 32 位整数硬存截断时机不对两个不同的报文可能算出同一个校验和log 里就会出现「明明校验和错了但接收端照样回 ACK」的诡异现象。做法上我一般会单独写一个verify_checksum(pkt)函数跟发送端共用一个实现避免两边的算法漂移。2.2 RDT 2.2 与 RDT 3.0冗余 ACK 设计成关键转折点RDT 2.2 解决的问题是「ACK 包本身也可能出现位错」。这意味着接收端传回来的 ACK 有可能在信道里被翻转发送端如果拿一个错误的 ACK 当作成功信号就会丢状态。课本标准答案是取消 NAK改用「对最后一个正确收到包的冗余 ACK」——接收端每收到一个新包不管它是不是乱的都回当前期望序号的 ACK。发送端收到重复 ACK 就明白上一个 ACK 丢失或损坏了但不急着重发那是 RDT 3.0 的事。RDT 3.0 在这个基础上加了超时重传。发送端发出数据后启动倒计时定时器如果超时还没等到正确 ACK就重发当前包。这份报告里明确写了「以上出错均能在超时之后重发」指的就是把位错和 ACK 损坏都收敛到同一个兜底机制上。实现上要注意定时器是对「最旧未确认包」启动的不是对每个包各起一个定时器。# RDT 3.0 发送端状态机伪代码 start_timer() # 发出包后启动单个定时器 while True: event wait_for_event() # 等待 ACK / 定时器超时 if event.type ACK_RECEIVED: if not verify_checksum(event.pkt): continue # ACK 位错忽略等待超时 stop_timer() seq 1 - seq elif event.type TIMEOUT: udt_send(current_pkt()) # 重发当前未确认包 start_timer()stop_timer()必须放在校验和验证通过之后。我见过一个翻车现场发送端收到错误 ACK 后直接把定时器停了然后永远等不到重发log 看起来就像「信道丢包但协议无动于衷」。这个顺序问题非常隐蔽因为错误 ACK 出现的概率不高跑几十轮才触发一次你不刻意构造位错场景根本观察不到。2.3 三份 log 的对照读法做完三段迭代你的目录下应该有三份 log。判断实现是否正确不是看它「跑通了」而是看三份 log 在同样的故障注入下表现不同log 文件注入的故障应该观察到的现象rdt2.0.log数据包位错接收端丢弃坏包不产生 ACK发送端继续轮询队列队列为空rdt2.2.logACK 包位错发送端校验和失败拒绝该 ACK接收端持续回冗余 ACKrdt3.0.log数据包丢失定时器超时发送端重发相同序号log 中出现连续相同的发送序号刚写完的人最容易把 RDT 2.0 和 RDT 2.2 的 log 混为一谈因为两版都是「校验和出错→不确认」。区分它们只有一个办法看 log 里有没有接收端的「冗余 ACK」记录。RDT 2.0 没有冗余 ACK接收端对坏包是完全沉默的RDT 2.2 则要求接收端对每个正确包都回当前期望序号的 ACK即使它跟上一个包重复。如果你的 RDT 2.2 log 里看不到重复 ACK说明接收端的 ACK 逻辑还没改过来。3. 选择响应协议逐个应答背后的窗口与缓存设计3.1 选择重传 vs 回退 N 步为什么接收端要逐个应答报告里第四个实验叫「选择响应协议」本质上就是选择性重传Selective Repeat。接收端对于每一个校验和正确的接收包都进行应答不因为某个包出错就把后面的包全部丢掉。这跟 Go-Back-N 有本质区别GBN 接收端只接受按序到达的包乱序的包直接丢弃而选择重传里接收端会把乱序但正确的包缓存起来等缺失的包补上之后一并交给上层。这一点可以直接从 log 里验证如果接收端收到 3 号包时 2 号包还没到GBN 的 log 会显示「丢弃 3 号包」而选择重传的 log 会显示「缓存 3 号包应答 2 号 ACK」。应答的序号是接收端期望的序号不是实际收到的序号这是最容易看岔的地方。看代码的话接收端的核心分支大概是这样的# 选择重传接收端逻辑伪代码 if verify_checksum(pkt): if pkt.seq expected_seq: deliver_to_upper_layer(pkt) expected_seq 1 # 检查缓存中是否有连续包可以继续递交 while has_cached(expected_seq): deliver_to_upper_layer(cache_pop(expected_seq)) expected_seq 1 else: cache_pkt(pkt) # 乱序包先缓存 send_ack(expected_seq - 1) # 回应的是「已连续收到的最后序号」 else: ignore(pkt) # 校验和错误丢弃关键点是用expected_seq标记连续边界send_ack(expected_seq - 1)告诉发送端到这个序号为止都是连续收到的你只缺中间那些空洞。这跟 RDT 2.2 的冗余 ACK 长得一样但语义不同——RDT 2.2 是停等协议下的冗余确认选择重传里这是带窗口的流水线确认。3.2 发送端窗口不是所有未确认包都要重传选择重传的发送端要维护一个滑动窗口窗口内可能有多个已发送但未确认的包。定时器超时后只重传那个超时的包而不是把窗口里所有包都重发一遍。窗口大小和序号空间有个硬约束窗口大小不能超过序号空间的一半否则接收端无法区分「新包」和「重传的旧包」。每次超时事件里发送端要维护一个dup_ack_count变量连续收到相同 ACK 达到阈值Reno 里是 3 次就触发快速重传。这块你会在第 4 章看到它和拥塞控制联动。选择重传阶段还没有拥塞窗口只有接收窗口所以发送端只关心一个问题哪些包的 ACK 还没到各自对应的定时器什么时候超时。# 发送端超时处理伪代码 def on_timeout(seq): if seq in window: udt_send(make_pkt(seq, buf[seq], checksum(buf[seq]))) start_timer(seq) # 为该包重启独立定时器选择重传的每个未确认包都需要独立计时。如果只用一个全局定时器超时后重发的可能是窗口里最旧的那个包但丢的假设上却是另一个log 里会出现大量无意义重传吞吐直接崩掉。这是很多实现跑不出理想曲线的首要原因。3.3 性能差异从 log 里的重传次数反推窗口行为对比实验报告里 RDT 3.0 和选择重传的 log最直观的指标是「重传次数」。同样的丢包率下RDT 3.0 每丢一个包就重发一个而选择重传因为接收端缓存了乱序包发送端只需要补发空洞。真正拉大差距的是多包丢失场景。假设窗口是 8一次突发丢包丢了 2 号和 5 号RDT 3.0 的 log 会有两次超时重传选择重传的 log 里除了两次超时还可能因为后续 ACK 触发快速重传而提前补发。你可以写个小脚本统计每份 log 里retransmit行的总数按 1000 个包为单位归一化重传率差 3 到 5 倍都属于正常范围。如果跑出来的结果相差 10 倍以上基本可以断定接收端的缓存没做好——乱序包到达后被丢了发送端被迫重传整个孤立区间的包行为退化成了 GBN。排查时先看 log 里有没有cache标签再看缓存递交后的deliver是否连续。4. Reno 拥塞控制的完整链路慢开始、快恢复与 cwnd 可视化4.1 慢开始与拥塞避免cwnd 的爬升路径从头看到尾进入 Reno 阶段发送端的窗口从「接收窗口」升级为「拥塞窗口 cwnd 和接收窗口的最小值」。这份实验的要求是解释慢开始、拥塞避免、快重传、快恢复、乘法减小五类行为全部通过 log 文件验证。慢开始的规则是cwnd 从 1 开始每个传输轮次结束翻倍。一个传输轮次不是「发一个包」的时间而是「把当前 cwnd 个包全部发出去并收到对应 ACK」的往返。因此第 1 轮发 1 个第 2 轮发 2 个第 3 轮发 4 个指数增长到 ssthresh 之前。拥塞避免阶段cwnd 每个轮次只加 1。这两个阶段的切换点就是 ssthresh。лог 里观察 cwnd 序列会看到一段陡峭的 1、2、4、8 曲线撞到 ssthresh 后变成平缓的 9、10、11、12。这个拐点如果不在 log 里你根本没法跟面试官或老师解释「你确实实现了拥塞避免」。发送端每个轮次的处理逻辑报告里给出的解决方案可以归成这样# 拥塞控制发送端轮次处理伪代码 def on_ack(ack): if cwnd ssthresh: cwnd * 2 # 慢开始指数增长 else: cwnd 1 # 拥塞避免线性增长 log_round(seq_no, ack_no, cwnd, ssthresh) def on_loss(): ssthresh max(cwnd // 2, 2) # 乘法减小阈值减半 cwnd ssthresh # Reno 快恢复后从新阈值开始log_round就是报告中说的「每经过一个传输轮次后输出当前网络状态」。它输出的四个字段我建议固定成当前发送包序号、当前接收包序号、cwnd、ssthresh。发送序号和接收序号帮助你定位这轮对应的数据区间cwnd 和 ssthresh 告诉你协议正处于哪个阶段。4.2 快重传与快恢复三个重复 ACK 触发的分水岭快重传的触发条件不是超时而是连续收到 3 个重复 ACK。Reno 的快恢复处理是ssthresh 减半cwnd 减半有些实现是 cwnd ssthresh然后进入拥塞避免而不是像 Tahoe 那样把 cwnd 降到 1 重新慢开始。这里有一个实现层面的坑快重传和慢开始的「乘法减小」都会修改 ssthresh如果你在on_loss()里同时被超时和快速重传两个路径调用ssthresh 会被减两次。实验过程中合理做法是让超时进入「慢开始重新起步」而快速重传只做 ssthresh 减半并维持线性增长两条路径分开处理。日志里区分两种丢包处理的办法是看重传后的第一个 cwnd 值如果是接近 ssthresh 的大值说明走的是快恢复如果变成 1那就是超时重传后重新慢开始。这个差异非常明显扫一眼就能判断实现有没有串线。4.3 解决「log 看不出阶段」的核心手段轮次级状态输出报告的 2 分困难题里写得很实在最大的困难是无法单独从 log 文件中直接看出慢开始以及拥塞避免等过程。原因很典型——传统实验框架的 log 记录的是「包级事件」比如发送了哪个序号、收到了哪个 ACK这些事件本身不携带 cwnd 信息你把几百行日志从头翻到尾也画不出窗口变化。我当时用的方法跟报告里写的一致在每个传输轮次结束后额外输出一条状态行。代码上就是在on_ack()的结尾加一行输出# 每轮次结束输出当前窗口状态python logger.info(fround{round_count} send_seq{next_seq} ack_seq{last_ack} fcwnd{cwnd} ssthresh{ssthresh} state{tcp_state})state字段是我自己加的取值为SS慢开始、CA拥塞避免、FR快恢复这样后续分析脚本可以直接按状态字段做统计不用再靠 cwnd 的数值变化反推阶段。加上这个字段之后log 的可读性直接从「黑匣子」变成「透明链路」。这份 log 样例大概长这样round1 send_seq0 ack_seq-1 cwnd1 ssthresh8 stateSS round2 send_seq1 ack_seq0 cwnd2 ssthresh8 stateSS round3 send_seq3 ack_seq2 cwnd4 ssthresh8 stateSS round4 send_seq7 ack_seq6 cwnd8 ssthresh8 stateCA round5 send_seq15 ack_seq14 cwnd9 ssthresh8 stateCA看到第 4 轮 cwnd 撞到 ssthresh8状态从 SS 切成 CA整个拥塞控制的过程一眼就明白了。这份报告后面所有阶段论证靠的就是这一行日志。5. 避坑清单日志分析、超时参数与迭代顺序的常见问题5.1 现象log 文件几百行却看不出慢开始和拥塞避免的边界原因日志只记录了包收发事件没有输出 cwnd 和 ssthresh。包级事件的信息量不够你只能看到「发了、确认了」看不到窗口在怎么变化。 解决每个传输轮次结束后输出状态行至少包含发送包序号、接收包序号、cwnd、ssthresh。不要在发送函数里插日志要在收到 ACK 并完成窗口更新之后再打否则打出来的是旧窗口值。5.2 现象慢开始跳过了 ssthresh直接进入线性增长但阈值没变原因发送端代码里把慢开始的翻倍条件和拥塞避免的加一条件写反了或者判断条件用了cwnd ssthresh导致 cwnd 等于 ssthresh 的那一轮直接进位。 解决用if cwnd ssthresh做慢开始else做拥塞避免。同时确认 ssthresh 初始值不是 0有些框架默认 ssthresh0会直接跳过整个慢开始过程。5.3 现象快重传触发后cwnd 直接变回 1原因实现的是 TCP Tahoe 而不是 Reno。Tahoe 在快速重传后强制 cwnd1重新慢开始Reno 则是 ssthresh 减半、cwnd 减半进入快恢复。 解决检查丢包处理分支。Reno 的快恢复路径里重传后 cwnd 应该等于新 ssthresh而不是 1。如果题目要求 Reno这个值不对就是版本错误。5.4 现象重复 ACK 计数不触发快重传每次都等到超时原因dup_ack_count没有在收到新 ACK 时重置。例如连续收到 3 个重复 ACK 之后第 4 个是新 ACK计数逻辑若没清零再收到重复 ACK 就会提前触发。 解决收到任何「不等于当前期望序号」的 ACK 时累计收到新 ACK 时清零。快重传阈值固定为 3不要把它跟 ssthresh 混用。5.5 现象多份 log 之间时间戳对不上分析脚本无法合并原因不同迭代版本的 Logger 没有区分标记RDT 2.0 和 Reno 的日志格式混在一个文件里或者重启实验时没有清空旧文件。 解决每个版本单独一个 log 文件第一行写入版本号例如# rdt3.0或# reno。分析脚本按版本号分块处理不要依赖文件生成时间。6. 让 log 替你说话一个快速提取 cwnd 曲线的小脚本第 4 章加了轮状态输出之后还有一个收尾工作要做把 log 里的 cwnd 序列提取出来画成曲线或者算阶段占比。手工翻文件既不高效也不准确我习惯在实验结束后跑一个一次性脚本# 提取 cwnd 序列并按阶段统计python import re pattern re.compile( rround(\d).*?cwnd(\d) ssthresh(\d) state(\S) ) rounds, cwnds, states [], [], [] with open(reno.log) as f: for line in f: m pattern.search(line) if m: rounds.append(int(m.group(1))) cwnds.append(int(m.group(2))) states.append(m.group(4)) # 输出阶段切换点 for i in range(1, len(states)): if states[i] ! states[i - 1]: print(fround {rounds[i]}: {states[i-1]} - {states[i]}, cwnd{cwnds[i]})这个脚本只做一件事扫描round开头且带cwnd的状态行把阶段切换点打印出来。输出大概是round 4: SS - CA, cwnd8正好对应慢开始撞 ssthresh 的那一轮。如果 log 里没有打印state字段你也可以用 cwnd 的序列自己判断连续翻倍是慢开始连续加一是拥塞避免。我一般还会顺手算一下每个阶段的轮次占比。慢开始占的轮次少但发出去的包多拥塞避免轮次多但每个轮次只多一个包这个对比能直观说明两种增长方式的差异。把这些数据直接写进实验报告的分析段落比单纯贴 log 截图有说服力得多。另外说一个我自己的习惯每次实验前先跑一遍回归把前一版 log 备份下来用 diff 对比本次改动对行为的影响。RDT 2.0 到 2.2 的改动如果让 2.0 的 log 也变了说明你改坏了公共的校验或确认逻辑而不是只加了新功能。从那以后我每次跑拥塞控制实验都强制走一遍这个流程先确认新 log 第一行有 version 标记再确认每轮状态行里有 cwnd 和 ssthresh最后才跑长时模拟。这套检查帮我省掉的排错时间远比写脚本花掉的时间多希望帮到你。本文还有配套的精品资源点击获取

相关新闻

K210边缘AI人脸检测与识别实战:硬件约束下的算法落地

K210边缘AI人脸检测与识别实战:硬件约束下的算法落地

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

2026/10/4 7:10:48 阅读更多 →
ZCode三端一体实测:上下文连贯、DeepSeek接入与隐私边界

ZCode三端一体实测:上下文连贯、DeepSeek接入与隐私边界

1. 先看清"三端一体"到底在解决什么ZCode把自己定位成"桌面浏览器终端"三端一体的AI编程工作台,这个口号我一开始是持保留态度的。市面上挂"下一代编程工具"招牌的产品太多了,真正用起来不别扭的没几个。但大半个月实测下…

2026/10/4 7:10:48 阅读更多 →
Linux 命令速查:zcat 不解压查看 gzip 压缩包内容详解

Linux 命令速查:zcat 不解压查看 gzip 压缩包内容详解

文档教程 【免费下载链接】linux-command Linux命令大全搜索工具,内容包含Linux命令手册、详解、学习、搜集。https://git.io/linux 项目地址: https://gitcode.com/GitHub_Trending/linux/linux-command 点击查看 免费下载 zcat 是 Linux/gzip 工具族中…

2026/10/4 7:10:48 阅读更多 →

最新新闻

GLiNER2.5-Decide进阶技巧:带描述的标签与0-10序数评分,精确驾驭私有分类体系

GLiNER2.5-Decide进阶技巧:带描述的标签与0-10序数评分,精确驾驭私有分类体系

GLiNER2.5-Decide进阶技巧:带描述的标签与0-10序数评分,精确驾驭私有分类体系 【免费下载链接】GLiNER2.5-Decide 项目地址: https://ai.gitcode.com/hf_mirrors/fastino/GLiNER2.5-Decide GLiNER2.5-Decide 是 GLiNER2.5 家族中的 340M 参数英文…

2026/10/4 7:48:10 阅读更多 →
基于PyTorch的CNN柑橘成熟度识别实战:从数据预处理到模型部署

基于PyTorch的CNN柑橘成熟度识别实战:从数据预处理到模型部署

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

2026/10/4 7:48:10 阅读更多 →
机械臂源码解析:从DH建模到ROS控制的工程闭环

机械臂源码解析:从DH建模到ROS控制的工程闭环

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

2026/10/4 7:48:10 阅读更多 →
Zabbix实战:从零监控交换机路由器防火墙的完整指南

Zabbix实战:从零监控交换机路由器防火墙的完整指南

做网络运维这些年,被领导半夜打电话问“交换机是不是挂了”的次数太多了。早期我都是登录每一台设备去看CPU、看端口流量,设备多了根本不现实,后来上了Zabbix之后才算把网络设备的监控真正串起来了。这篇文章就用我实际部署和维护的经验&…

2026/10/4 7:48:10 阅读更多 →
QT+C++打地鼠游戏毕业设计:从零实现与答辩避坑指南

QT+C++打地鼠游戏毕业设计:从零实现与答辩避坑指南

简介:这是一份基于QT与C实现的打地鼠游戏完整源码,面向计算机相关专业的毕业设计、课程设计以及入门级项目开发学习者。项目在QT环境下编译运行,核心依托QT信号与槽机制完成界面与业务逻辑的关联,并支持动态调整地鼠出现速度等参数…

2026/10/4 7:48:10 阅读更多 →
AI Agent 全链路可观测实践:Langfuse 接入 FastAPI + LangChain + LangGraph

AI Agent 全链路可观测实践:Langfuse 接入 FastAPI + LangChain + LangGraph

最近在做一个基于 FastAPI LangChain LangGraph 的客服类 AI Agent,模型调用本身不贵,真正让我头疼的是“出了事没法查”。生产环境里用户问了一句稍微绕弯的话,Agent 就开始一本正经地胡说八道,工具调用链走到一半直接断掉&…

2026/10/4 7:47:10 阅读更多 →

日新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

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

2026/10/4 1:00:58 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

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

2026/10/4 1:00:58 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

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

2026/10/4 1:00:58 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

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

2026/10/4 1:00:58 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

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

2026/10/4 1:00:58 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

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

2026/10/4 1:00:58 阅读更多 →

月新闻

我发现了一个新思路:用 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/2 10:36:31 阅读更多 →
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/3 9:42:35 阅读更多 →
黑夜航拍船只数据集训练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/3 9:42:36 阅读更多 →