C#实现西门子S7通讯:从协议帧拆解到类库封装实战
简介这份源码资源面向工业自动化与上位机开发方向的C#程序员聚焦西门子S7系列PLC的通讯实现帮助开发者打通.NET程序与PLC之间的数据交互链路。压缩包共39个文件约244KB以cs源码文件为主配合sln解决方案、csproj工程配置、resx与resources界面资源、config配置及exe、dll等编译产物结构完整可直接在Visual Studio中打开运行。源码基于Sharp7通讯库涵盖连接建立与断开、PLC地址区映射、布尔与整型实型等数据类型转换、ReadArea与WriteArea读写操作、异常捕获与错误码检查等关键环节并配有Windows Forms实用界面通过按钮、文本框与后台通讯逻辑联动同时涉及多线程与定时器实现持续通讯。已有487人学习下载适合希望快速掌握S7通讯流程、对照调试并移植到自己项目中的开发者参考。1. 从一根网线到读写DB块S7通讯在C#上位机里到底怎么落地车间里一台西门子S7-1200跑着产线逻辑上位机需要每秒把产量、节拍、报警状态抓过来还要往PLC写配方参数。很多做C#上位机的朋友第一反应是找现成驱动结果发现要么收费要么版本对不上要么连上之后读DB块全是乱码。这个标题讲的就是用C#自己实现与西门子PLC的S7通讯不依赖商业库直接走ISO-on-TCP协议跟PLC对话。适合有C#基础、做过WinForm或WPF上位机、手头有西门子S7-1200/1500/300/400PLC的工程师。核心要解决的问题只有三个连得上、读得对、写得进。连得上靠TCP握手和COTP连接读得对靠理解S7协议的数据区寻址写得进靠PDU里参数段的正确组装。源码层面一套能跑的S7通讯库大概800到1200行C#包含连接管理、PDU封装、数据解析三个模块下面从协议帧结构开始拆。2. S7协议帧拆解从TCP连接到读写请求的完整链路2.1 为什么不能直接发TCP字节流西门子PLC的以太网口开放的是ISO-on-TCPRFC1006端口默认102。你用Socket连上之后直接发一段自定义字节PLC不会理你。因为S7通讯在TCP之上还叠了两层COTPConnection-Oriented Transport Protocol和S7 Communication。COTP负责建立逻辑连接通道S7层负责具体的读写请求。常见做法是分三步走先发COTP连接请求CR收到确认CC后再发S7通讯初始化最后才是读写PDU。跳过任何一步PLC都会直接断开连接而且不给你任何错误提示这就是很多人说的“连上了但读不到”的玄学来源。COTP连接请求帧的结构是固定的TPKT头4字节 COTP头3字节 参数。TPKT头里版本号写0x03长度字段填整个包的长度。COTP头的PDU类型写0xE0表示连接请求后面跟目标TSAP和源TSAP。TSAP是Transport Service Access Point的缩写可以理解为PLC上的“门牌号”。S7-1200/1500的机架0槽位1对应TSAP是0x0100机架0槽位2对应0x0200。写错TSAPPLC会回一个COTP拒绝帧连接直接断。// 构建COTP连接请求帧 byte[] BuildCotpConnectionRequest(byte rack, byte slot) { // TPKT头: 版本3, 保留0, 长度大端 var tpkt new byte[] { 0x03, 0x00, 0x00, 0x16 }; // COTP头: 长度17, PDU类型0xE0(连接请求) var cotp new byte[] { 0x11, 0xE0, 0x00, 0x00, 0x00, 0x01, 0x00 }; // 目标TSAP: 0x01 rack*0x20 slot byte tsapHigh (byte)(0x01 rack * 0x20 slot); var dstTsap new byte[] { 0x02, 0x01, tsapHigh }; // 源TSAP: 固定0x0100 var srcTsap new byte[] { 0x02, 0x01, 0x00 }; // 参数: 最大TPDU大小 var param new byte[] { 0xC0, 0x01, 0x0A }; return tpkt.Concat(cotp).Concat(dstTsap).Concat(srcTsap).Concat(param).ToArray(); }这段代码里rack和slot是PLC的物理位置S7-1200通常写0和1。tsapHigh的计算方式是西门子内部约定0x01是连接类型加上机架号和槽位号偏移。param里的0xC0表示协商TPDU大小0x0A代表1024字节。如果PLC返回的CC帧里TPDU大小是0x07480字节后续读写PDU就不能超过这个值否则PLC会丢弃请求。这个参数在长数据读写时特别关键读一个200字节的DB块没问题读2000字节就必须分片。2.2 S7读写PDU的组装逻辑COTP连接建立后发一个S7通讯初始化帧PLC回复后就可以发读写请求了。S7读写PDU的结构比COTP复杂但拆开看就是三部分S7头10字节 参数段12字节 数据段可选。S7头里最重要的是ROSCTR字段读请求写0x01写请求写0x05。参数段里包含功能码、数据区类型、DB号、起始地址、长度。数据区类型用0x81表示输入区I0x82表示输出区Q0x83表示位存储区M0x84表示DB块。DB号占2字节起始地址占3字节注意是位地址不是字节地址长度占2字节。// 构建S7读请求PDU byte[] BuildS7ReadRequest(byte[] pduRef, ushort dbNumber, int startByte, ushort length) { // S7头: 协议ID0x32, ROSCTR0x01(读), 保留, PDU引用, 参数长度, 数据长度 var s7Header new byte[] { 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00 }; // 参数段: 功能码0x04(读), 项数1 var param new byte[] { 0x04, 0x01 }; // 项: 变量规格0x12, 长度, 语法ID0x10, 数据区类型0x84(DB), DB号, 起始地址(位), 长度 var item new byte[] { 0x12, 0x0A, 0x10, 0x84, (byte)(dbNumber 8), (byte)(dbNumber 0xFF), (byte)(startByte 8), (byte)(startByte 0xFF), 0x00, (byte)(length 8), (byte)(length 0xFF) }; // 合并并更新长度字段 var result s7Header.Concat(param).Concat(item).ToArray(); result[4] pduRef[0]; result[5] pduRef[1]; // PDU引用 result[8] 0x00; result[9] 0x0E; // 参数长度14字节 return result; }pduRef是PDU引用号每次请求递增PLC回复时会带回同样的引用号用来匹配请求和响应。startByte是字节偏移但协议里要求左移3位变成位地址所以代码里写的是startByte 8和startByte 0xFF实际发送时第3个字节固定0x00。length是读取的字节数读DB块时按字节算读I/Q/M区时按位算。如果读的是BOOL量长度写1起始地址写位偏移如果读的是REAL长度写4起始地址写字节偏移左移3位。这个细节搞错读出来的数据会整体偏移比如读DB1.DBD0读成了DB1.DBD1。写请求的PDU结构类似ROSCTR改成0x05参数段里功能码改成0x05数据段里带上要写入的字节。写请求比读请求多一个数据段数据段里包含传输大小和实际数据。写BOOL量时数据段里是0x01或0x00写REAL时数据段里是4字节的IEEE754浮点数。注意字节序S7协议是大端C#的BitConverter默认是小端写之前要反转数组。2.3 连接保持与心跳机制PLC的S7连接有超时机制默认空闲超过一段时间通常30秒到几分钟会主动断开。上位机如果只是定时读写问题不大但如果读写间隔超过30秒就需要发心跳包。心跳包最简单的方式是读一个固定地址比如读M0.0一个字节。有些工程师用S7通讯初始化帧当心跳但那个帧只在连接建立时发一次重复发PLC会报错。我一般会在定时器里每10秒读一次DB1.DBB0既当心跳又当状态检测。如果连续3次读失败就重连。重连逻辑要注意先关闭Socket再重新走COTP连接流程。不要试图在旧连接上重发请求PLC那边可能还保留着半开连接导致新连接被拒绝。Socket的LingerState属性建议设为trueLingerTime设为0这样关闭时直接发RST不经过四次挥手避免TIME_WAIT状态堆积。这个设置在高频重连场景下特别有用血泪经验是没设这个参数跑一晚上上位机就报“无法连接”重启才好。3. 用C#把S7通讯封装成可复用的类库3.1 类结构设计与核心字段一套能用的S7通讯库不需要太复杂我一般拆成三个类S7Client负责连接和PDU收发S7DataConverter负责字节数组和C#类型的互转S7Address负责解析地址字符串。S7Client里核心字段就几个TcpClient对象、NetworkStream流、ushort PduRef引用号、int PduSize协商后的PDU大小、bool IsConnected状态标志。构造函数接收IP、机架号、槽位号连接方法里先建TCP连接再发COTP请求再发S7初始化三步都成功才把IsConnected置true。public class S7Client { private TcpClient _tcpClient; private NetworkStream _stream; private ushort _pduRef 0; private int _pduSize 480; public bool IsConnected { get; private set; } public bool Connect(string ip, byte rack, byte slot) { _tcpClient new TcpClient(); _tcpClient.LingerState new LingerOption(true, 0); _tcpClient.Connect(ip, 102); _stream _tcpClient.GetStream(); // 发COTP连接请求 var cotpReq BuildCotpConnectionRequest(rack, slot); _stream.Write(cotpReq, 0, cotpReq.Length); var cotpResp ReadResponse(7); if (cotpResp[5] ! 0xD0) return false; // 0xD0是CC确认 // 发S7初始化 var s7Init BuildS7InitRequest(); _stream.Write(s7Init, 0, s7Init.Length); var s7Resp ReadResponse(10); if (s7Resp[7] ! 0x00) return false; _pduSize (s7Resp[8] 8) | s7Resp[9]; IsConnected true; return true; } }ReadResponse方法负责从流里读固定长度的响应先读4字节TPKT头拿到总长度再读剩余部分。注意NetworkStream.Read不保证一次读完要循环读直到读满。_pduSize从S7初始化响应里取S7-1200通常返回480S7-1500返回960。后续读写请求的数据长度不能超过_pduSize - 1818是S7头和参数段的固定开销超了就要分片。3.2 读DB块数据的完整调用链读DB块是上位机最常用的操作。假设要读DB100从偏移0开始的20个字节调用链是ReadDb(100, 0, 20)→ 组装PDU → 发送 → 接收 → 解析。解析时要注意响应PDU里数据段前面有4字节的返回码和传输大小真正的数据从第18字节开始S7头10字节参数段2字节项返回码4字节数据长度2字节。如果返回码不是0xFF说明读取失败常见错误码0x05表示地址越界0x0A表示对象不存在。public byte[] ReadDb(ushort dbNumber, int startByte, ushort length) { if (!IsConnected) throw new InvalidOperationException(未连接); if (length _pduSize - 18) throw new ArgumentException(长度超PDU限制); _pduRef; var request BuildS7ReadRequest(BitConverter.GetBytes(_pduRef), dbNumber, startByte, length); _stream.Write(request, 0, request.Length); var response ReadResponse(10); // 检查返回码 if (response[17] ! 0xFF) throw new Exception($读取失败, 错误码: {response[17]:X2}); // 提取数据 var data new byte[length]; Array.Copy(response, 21, data, 0, length); return data; }response[17]是项返回码0xFF表示成功。response[21]是数据起始位置前面21字节分别是TPKT头4字节 COTP头3字节 S7头10字节 参数段2字节 项返回码1字节 数据长度1字节。这个偏移量是固定的但不同PLC型号可能有1到2字节差异建议先用Wireshark抓一次包确认。读上来的byte[]再根据数据类型转换BOOL取第0位INT用BitConverter.ToInt16反转后转REAL用BitConverter.ToSingle反转后转。3.3 写DB块与BOOL量的参数差异写DB块和读DB块最大的区别在数据段。写请求的PDU里参数段后面跟一个数据段数据段的前2字节是传输大小大端后面是实际数据。写BOOL量时数据段里是1字节0x01表示置位0x00表示复位。写REAL时数据段里是4字节注意C#的BitConverter.GetBytes(float)返回小端要Array.Reverse反转成大端再拼进去。public void WriteDb(ushort dbNumber, int startByte, byte[] data) { if (!IsConnected) throw new InvalidOperationException(未连接); _pduRef; var s7Header new byte[] { 0x32, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00 }; var param new byte[] { 0x05, 0x01, 0x12, 0x0A, 0x10, 0x84, (byte)(dbNumber 8), (byte)(dbNumber 0xFF), (byte)(startByte 8), (byte)(startByte 0xFF), 0x00, (byte)(data.Length 8), (byte)(data.Length 0xFF) }; var dataSegment new byte[] { 0x00, (byte)data.Length }.Concat(data).ToArray(); var request s7Header.Concat(param).Concat(dataSegment).ToArray(); request[4] (byte)(_pduRef 8); request[5] (byte)(_pduRef 0xFF); _stream.Write(request, 0, request.Length); var response ReadResponse(10); if (response[17] ! 0xFF) throw new Exception($写入失败, 错误码: {response[17]:X2}); }写BOOL量时data传new byte[] { 0x01 }或new byte[] { 0x00 }startByte传位偏移。比如写DB100.DBX2.3startByte传2 * 8 3 19。写REAL时data传4字节startByte传字节偏移左移3位。这个位地址和字节地址的转换是S7通讯里最容易翻车的地方建议封装一个S7Address.Parse方法把“DB100.DBD0”这种字符串解析成DB号、起始位地址、长度三个参数调用方不用手算。3.4 批量读写与分片策略当读取长度超过_pduSize - 18时必须分片。比如读DB100从0开始的1000字节_pduSize是480每片最多读462字节需要分3片0-461、462-923、924-999。分片读完之后在内存里拼接。写操作同理每片写462字节。分片时要注意每片的起始地址要按字节对齐不能跨字或跨双字边界否则PLC可能返回错误。我一般按2字节对齐分片读REAL数组时按4字节对齐。分片读的代码逻辑是在ReadDb外面包一层循环每次读Math.Min(remaining, maxChunk)把结果追加到MemoryStream里。分片写类似每次写Math.Min(remaining, maxChunk)直到写完。分片会增加通讯轮次1000字节读3次比读1次慢但这是协议限制绕不过去。如果对速度有要求可以把多个不连续的DB块合并到一个请求里S7协议支持一个PDU里带多个项但实现复杂度高一般项目用不上。4. 避坑与排查S7通讯里那些让人抓狂的瞬间4.1 连接成功但读DB块返回0x05错误码现象是COTP连接和S7初始化都成功IsConnected为true但一读DB块就抛异常错误码0x05。原因通常是DB块没有开启“允许PUT/GET通讯访问”。S7-1200/1500在TIA Portal里DB块属性里有一个“优化的块访问”选项默认勾选。勾选后DB块没有绝对地址S7通讯读不了。解决办法是右键DB块 → 属性 → 属性 → 取消勾选“优化的块访问”然后重新下载。取消后DB块会显示偏移量比如DB100.DBD0就能读了。注意取消优化访问后DB块里的变量地址会重新分配上位机里的地址要同步改。4.2 读上来的REAL值全是乱码现象是读DB块返回的字节数组长度对但转成float后是1.234E38这种离谱值。原因是字节序搞反了。S7协议是大端C#的BitConverter.ToSingle按小端解析。正确做法是先Array.Reverse再转或者用BinaryPrimitives.ReadSingleBigEndian。另外注意如果读的是DINT或DWORD同样要反转。BOOL量不用反转因为只取一个字节的第0位。字符串要特别注意S7的STRING类型前2字节是最大长度和当前长度真正的字符从第3字节开始读的时候长度要多加2。4.3 高频读写时PLC返回0x03错误码现象是上位机每秒读10次跑几分钟后PLC开始返回0x03然后连接断开。原因是PLC的通讯资源有限S7-1200默认最多支持8个并发连接每个连接有请求队列。上位机发得太快队列满了PLC就拒绝。解决办法是在上位机加一个请求间隔最小50ms或者用异步队列串行化请求。我一般会在S7Client里加一个SemaphoreSlim同一时间只允许一个请求在飞发完再发下一个。这样虽然吞吐量降了但稳定性大幅提升。另外读写请求的PDU引用号要严格递增不能重复重复了PLC也会报错。4.4 连接一段时间后自动断开现象是上位机跑着跑着IsConnected还是true但读写全部超时。原因是PLC侧的空闲超时到了主动断开了TCP连接但上位机的Socket没有收到FIN包可能被防火墙拦截导致状态不一致。解决办法是加心跳每10秒读一次固定地址连续3次失败就重连。重连时先_tcpClient.Close()再Dispose()然后重新new TcpClient()。不要复用旧的TcpClient对象复用会导致端口占用。另外NetworkStream.Read要设超时_stream.ReadTimeout 3000超时抛异常就触发重连。4.5 写BOOL量时PLC没反应现象是写请求返回0xFF成功但PLC里的BOOL量没变化。原因是写BOOL量时数据段里的值不是0x01和0x00而是0x01和0x00左移了位偏移。S7协议写BOOL量时数据段里是一个字节但只有对应位有效。比如写DB100.DBX2.3数据段里的字节应该是0x08第3位置1而不是0x01。如果写0x01实际置位的是DBX2.0。解决办法是写BOOL量时先读当前字节用位运算修改目标位再写回去。或者直接构造正确的位掩码1 (bitOffset % 8)。这个坑我踩过两次第一次以为是PLC没刷新第二次才反应过来是位偏移。5. 进阶技巧用Wireshark抓包验证与性能调优5.1 抓包验证PDU组装是否正确S7通讯调试最有效的手段是Wireshark抓包。在Windows上装Wireshark选对网卡过滤条件写tcp.port 102。连上PLC后先看COTP握手第一个包是CR0xE0第二个包是CC0xD0。如果CC没出现说明TSAP写错了。然后看S7初始化请求里ROSCTR是0x01功能码0xF0响应里返回PDU大小。最后看读写请求读请求的ROSCTR是0x01写请求是0x05。如果Wireshark里看到的PDU跟你代码里组装的不一样逐字节对比通常错在长度字段或地址偏移。抓包时注意Wireshark默认不解析S7协议要在“分析 → 启用的协议”里勾选S7COMM。勾选后能看到友好的树形结构直接展开看“Parameter”和“Data”字段。如果PLC返回错误码Wireshark里会显示“Error Class”和“Error Code”比代码里抛异常直观得多。我一般会在代码里加一个DebugMode开关打开后把每次发送和接收的字节数组打印到日志跟Wireshark抓包对照定位问题快很多。5.2 用连接池管理多PLC并发一个上位机连多台PLC时每台PLC一个S7Client实例不要共用一个。共用一个会导致PDU引用号混乱而且一台PLC断开会影响其他PLC。连接池的实现方式是ConcurrentDictionarystring, S7Clientkey是IP机架槽位value是客户端实例。读写时从字典里取取不到就新建并连接。定时器里遍历字典对每个客户端发心跳失败的移除并重连。注意ConcurrentDictionary的线程安全读写操作要加锁或者用SemaphoreSlim串行化。多PLC并发时PLC的响应时间会变长因为上位机的CPU和网卡要分时处理。如果对实时性有要求可以把读写操作放到独立的Task里用Task.WhenAll并行发。但要注意并行发请求时每个S7Client的_pduRef要独立递增不能共享。我一般会在S7Client里用Interlocked.Increment保证原子性。另外并行请求的数量不要超过PLC的并发连接数S7-1200最多8个S7-1500最多32个超了会被拒绝。5.3 性能调优的3个关键参数第一个参数是_pduSize协商时尽量要大。S7-1200返回480S7-1500返回960这是PLC侧的限制改不了。但可以在S7初始化请求里把最大TPDU大小写大一点比如写0x0F2048PLC如果支持会返回更大的值。第二个参数是ReadTimeout默认3秒局域网里可以设1秒广域网设5秒。超时太短会导致误判重连太长会导致界面卡顿。第三个参数是分片大小不要按_pduSize - 18满打满算留2字节余量因为PLC可能在某些型号上多返回几个字节的填充。我一般按_pduSize - 20分片实测稳定。还有一个隐藏参数是TcpClient.NoDelay默认false表示启用Nagle算法会把小包合并发送。S7通讯的请求包通常很小几十字节Nagle算法会导致延迟增加。设_tcpClient.NoDelay true后请求立即发送响应快很多。这个参数在本地调试时感觉不明显但在产线环境里上位机跟PLC之间经过交换机Nagle算法可能引入10到50ms延迟。设了之后读写周期从100ms降到60ms左右。这个技巧是我在一个节拍要求很高的项目里发现的当时一直以为是PLC慢后来抓包才发现是Nagle算法在作怪。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

高通平台USB驱动实战:代码路径、抓包与排查手法

高通平台USB驱动实战:代码路径、抓包与排查手法

/* 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:21:57 阅读更多 →
MFC实现Modbus-TCP温湿度采集的工业级实践

MFC实现Modbus-TCP温湿度采集的工业级实践

/* 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:21:56 阅读更多 →
Django学生选课系统实战:关系建模与权限分层

Django学生选课系统实战:关系建模与权限分层

1. 这个“简易学生选课系统”到底在解决什么真实问题?我第一次带实习生做 Django 项目时,常被问:“老师,学完 CRUD 就算会 Web 开发了吗?”——这个问题背后藏着一个普遍误区:把框架当语法书背,…

2026/10/4 7:21:56 阅读更多 →

最新新闻

Magic3D 两阶段文本到3D生成实战:从粗几何到细纹理的完整复现指南

Magic3D 两阶段文本到3D生成实战:从粗几何到细纹理的完整复现指南

/* 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:56:14 阅读更多 →
openrig开源模块化支架:铝型材与3D打印的桌面搭建实战指南

openrig开源模块化支架:铝型材与3D打印的桌面搭建实战指南

1. 项目概述1.1 openrig 到底是什么先把话说明白:openrig 是一个标榜全开源、模块化、可复用的硬件支架/装置项目。它解决的问题非常具体——桌面设备的固定与承载。说的再直白一点,就是那些摄影灯、补光灯、摄像头、麦克风、树莓派、传感器模块、3D打印…

2026/10/4 7:56:14 阅读更多 →
从一网渔获到一篇论文:渔业资源毕业论文的 AI 工具分工指南 [特殊字符]

从一网渔获到一篇论文:渔业资源毕业论文的 AI 工具分工指南 [特殊字符]

如果你是农学 / 水产 / 渔业资源专业的学生,大概率会遇到这样一项很典型的毕业任务: 基于某近海、湖泊或河口的渔业资源调查数据,分析渔获物组成、优势种、生物多样性、资源量现状,并结合水温、盐度、水深、溶解氧等环境因子&…

2026/10/4 7:56:14 阅读更多 →
开题被导师批“逻辑散架”?云智变AI的AIPPT功能,可能比你更懂学术演示的“潜规则”

开题被导师批“逻辑散架”?云智变AI的AIPPT功能,可能比你更懂学术演示的“潜规则”

先讲一个你可能经历过的场景 开题答辩前一周,你把研究方案写成了PPT。每一页都塞满了文字,技术路线图用的是十年前那种方块箭头图,导师看完沉默了三秒,说了一句: “你这是在用Word的思维做PPT。” 论文答辩前三天&am…

2026/10/4 7:56:14 阅读更多 →
外链堆了很多,AI还是不引用你?一项追踪6.8亿次引用的研究给出了新信号

外链堆了很多,AI还是不引用你?一项追踪6.8亿次引用的研究给出了新信号

核心摘要:2026年5月发布的一项追踪6.8亿次AI引用记录的研究发现,品牌搜索量与AI引用可能性的相关系数为0.334,是目前已知最强的引用预测因子,明显强于反向链接数量。国内截至2026年7月18日对六个主流AI平台的实测也显示&#xff0…

2026/10/4 7:56:14 阅读更多 →
关闭 AWS CLI 命令输出分页器:`--no-cli-pager` 标志与 `cli_pager` 配置详解

关闭 AWS CLI 命令输出分页器:`--no-cli-pager` 标志与 `cli_pager` 配置详解

文档教程知识库 【免费下载链接】til :memo: Today I Learned 项目地址: https://gitcode.com/gh_mirrors/ti/til 点击查看 免费下载 AWS CLI 命令(如 aws rds describe-db-instances)常常返回大量 JSON 数据。默认情况下,结果会…

2026/10/4 7:55:13 阅读更多 →

日新闻

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 阅读更多 →