新闻详情

新闻详情

首页 / 资讯中心 / 详情

WinPcap UDP发包程序:绕过Socket协议栈手工构造整帧报文

发布时间:2026/9/28 2:42:50来源:尧图网络
WinPcap UDP发包程序:绕过Socket协议栈手工构造整帧报文
简介这是一份基于WinPcap实现的UDP发包程序源码包面向网络协议学习者、套接字编程初学者以及需要完成网络类课程设计的在校学生重点解决如何使用WinPcap库构造并发送自定义UDP数据报文的问题。程序借助WinPcap直接与网络接口卡交互在驱动层完成报文注入与普通套接字发送相比能更清晰展示UDP报头、数据载荷和校验和的生成过程适合用于局域网通信实验、协议分析演示及网络工具开发。压缩包共349个文件大小约5.94MB包含C工程源码、WinPcap依赖库、Visual Studio工程配置以及配套展示用的前端页面整体目录组织有序便于定位核心代码与运行说明。目前已有187人学习下载通过阅读源码可掌握设备枚举、数据包封装、校验计算和发送调用等关键步骤工程附带完整编译配置解压后可直接运行也方便进一步扩展为网络监控或自定义协议测试工具。1. 基于 WinPcap 的 UDP 发包程序绕开 Sendto把整帧报文握在手里前阵子要测一台网络设备对特定 UDP 流量的处理能力需求看着很简单按固定的源端口、固定载荷往目的端口发数据报。第一反应是拿 Python 的 socket 直接sendto结果在 Wireshark 里一抓就露馅了——TTL 是系统默认的 128源 IP 是网卡绑定的地址TOS 字段完全改不了。UDP 协议本身不复杂可一旦需求深入到「IP 头里每个字节都要我说了算」的粒度操作系统协议栈就是一个不听话的黑匣子。这篇文章拆一个基于 WinPcap 实现的 UDP 发包程序源码包讲清楚它如何绕开协议栈直发网卡、怎么手工组出以太网头加 IP 头加 UDP 头以及编译运行中最容易翻车的几个位置。它适合做网络设备验证、UDP 协议学习、报文构造这类场景的从业者。2. 选型与底层逻辑WinPcap 绕协议栈直发网卡和 Socket 有什么本质区别2.1 普通 UDP Socket 的局限协议栈替你做的每一件事都让你失去控制权用socket(AF_INET, SOCK_DGRAM, 0)加sendto()发包时数据流在用户态看着很简单但内核里其实走了一条很长的流水线UDP 层补上 UDP 头并计算校验和IP 层查路由表决定走哪个网卡、填源 IP 和目的 IP、算 IP 头校验和链路层再查 ARP 表找目的 MAC。这一整套动作没有一个能由应用层干预最后你发出的包长什么样全看协议栈心情。比如你想模拟一个来自某个特定地址的 UDP 探测包sendto只能填目的地址源地址根本不在参数里你想把 TTL 改成 1 去看设备对超时报文的响应得先翻注册表或者setsockopt(IP_TTL)而且改了之后是对整个 socket 生效不是对某一个包生效。至于 IP 头里的标识字段 ID、分片标志、TOS普通 UDP socket 连操作入口都没有。Windows 上还有个更尴尬的限制自 XP SP2 之后raw socket 的发送能力被大幅收紧想自己构造 IP 头发 UDP 包socket(AF_INET, SOCK_RAW, IPPROTO_UDP)这条路基本被堵死权限校验极严很多环境下直接失败。所以在 Windows 平台上做报文级发包WinPcap 几乎成了标配选项。2.2 WinPcap 的结构与 pcap_sendpacket用户态组包驱动级发送WinPcap 的架构分两层用户态是 wpcap.dll 和 packet.dll内核态是 NPF 驱动。应用程序调用pcap_sendpacket()时数据不是按「syscall → 协议栈 → 网卡」走的而是把用户态组好的完整以太网帧通过 packet.dll 交给 NPF 驱动由驱动直接写到网卡的发送环上。整个过程不经过 TCP/IP 栈所以没有谁能替你做主你给什么帧网卡就发什么帧。代价就是什么都要自己算。以太网头的目的 MAC、源 MAC、类型字段IP 头的版本号、总长度、校验和UDP 头的长度和校验和全部要手工填充。发出去的帧如果小于 60 字节网卡驱动会自动补 padding这个不用操心但帧内容里任何一个字节错了接收端解析出来的就是乱包。做一个选型对比能比较直观地看到两者的适用边界对比项普通 UDP SocketWinPcap 发包可控粒度载荷、目的端口、TTL 等少量参数从以太网头到载荷逐字节可控源 IP / TOS / 分片标志协议栈决定可完全自定义发送路径用户态 → 协议栈 → 网卡用户态 → NPF 驱动 → 网卡ARP 处理内核自动查询自己填 MAC填错就丢包配置门槛低几条 API 就够中需要懂报文结构典型场景常规业务通信网络测试、协议验证、流量构造2.3 压缩包里的库文件角色libwpcap.a、libpacket.a 和 WinPcap_UDP_Test.aps 都是什么这个源码包里的libwpcap.a和libpacket.a需要单独说一下。WinPcap 官方开发者包在 Windows 上默认提供的是wpcap.lib和packet.lib那是 MSVC 格式的导入库而.a后缀是 GNU 工具链格式说明这个包面向的是 MinGW 或 Code::Blocks 一类的编译环境。libwpcap.a对应 wpcap.dll 的高层 APIpcap_findalldevs、pcap_open_live、pcap_sendpacket这些函数都从它导入libpacket.a对应 packet.dll 的低层接口主要做设备访问和数据包收发。链接的时候两个库都要带上。WinPcap_UDP_Test.aps是 Visual Studio 的资源脚本缓存文件说明这个工程曾经用 VS 打开过但aps本身不是需要阅读的源码真正要看的还是工程里的.c源文件和.h头文件。至于压缩包里那一串以20140228124512421格式命名的时间戳文件看命名规则多半是打包机器上的编译中间产物或运行日志和源码逻辑无关解压后可以直接忽略不用费心去还原它是什么。3. 源码链路拆解从打开网卡、手工组 UDP 包到 pcap_sendpacket 发送3.1 文件清单与脑内定位拿到压缩包先找什么我拿到这类打包资源的第一步是把文件分三类源码、依赖库、杂项。按winpcap-udp-test这个工程名推断核心源码通常只有一个主文件十几 KB 左右入口函数是main()里面会依次做三件事枚举并打开网卡、构造 UDP 报文、循环发送。依赖库就是前面说的两个.a文件杂项是.aps和那串时间戳文件。先看打开网卡这一段。WinPcap 的设备名格式是\Device\NPF_{GUID}在代码里经常配合pcap_findalldevs使用因为手工输入那串 GUID 谁也记不住。#include pcap.h #include stdio.h #include string.h #include winsock2.h // 枚举本机所有 WinPcap 可见的网络接口打印出来供选择 void list_devices(void) { pcap_if_t *alldevs; char errbuf[PCAP_ERRBUF_SIZE]; if (pcap_findalldevs(alldevs, errbuf) -1) { fprintf(stderr, pcap_findalldevs error: %s\n, errbuf); return; } for (pcap_if_t *d alldevs; d; d d-next) { printf(%s - %s\n, d-name, d-description ? d-description : (no desc)); } pcap_freealldevs(alldevs); }pcap_findalldevs的第一个参数是链表指针的地址它会把所有接口信息挂在链上errbuf是错误缓冲任何 pcap 函数失败时都会往里写一段可读文本。拿到设备名之后再用pcap_open_live打开重点看它的四个参数snaplen设 65535 表示每帧完整捕获promisc设 1 表示混杂模式to_ms设 1000 是抓包读取超时发包场景下这个值影响不大。3.2 手工组包以太网头、IP 头、UDP 头的填充顺序与字节序陷阱打开设备之后就是整个程序的核心——把报文逐字节拼出来。由于要写内存区域我先定义三个结构体注意用#pragma pack(push, 1)防止编译器插入填充字节否则结构体大小不一致指针偏移就全错了。#pragma pack(push, 1) // 以太网头14 字节 typedef struct { unsigned char dst_mac[6]; unsigned char src_mac[6]; unsigned short ether_type; // 0x0800 IPv4 } eth_hdr_t; // IP 头20 字节不含选项 typedef struct { unsigned char ver_ihl; // 高4位版本低4位首部长IPv4 无选项时是 0x45 unsigned char tos; // 服务类型 unsigned short total_len; // IP 包总长含 IP 头 unsigned short id; // 标识字段 unsigned short frag_off; // 标志 片偏移 unsigned char ttl; unsigned char protocol; // 17 表示 UDP unsigned short checksum; unsigned int src_addr; unsigned int dst_addr; } ip_hdr_t; // UDP 头8 字节 typedef struct { unsigned short src_port; unsigned short dst_port; unsigned short length; // UDP 头 载荷长度 unsigned short checksum; } udp_hdr_t; #pragma pack(pop)组包时的主顺序是先填以太网头这决定了数据帧能不能在当前局域网里被送到目标机器再填 IP 头这是接收端路由和重组报文的依据最后填 UDP 头。每一层的多字节字段都要注意字节序CPU 是小端的但网络上跑的是大端所以端口、总长、校验和这类字段必须交给htons()/htonl()处理否则抓包工具里看到的端口就是反的。IP 头里的src_addr和dst_addr我用inet_addr()把点分十进制转成网络序的unsigned int赋值时保持网络序。total_len必须是20 8 payload_len这个长度同时还要回填到 UDP 头的length字段里漏掉任何一个接收端都会判定包异常。3.3 校验和计算IP 校验和与 UDP 伪头部是最大的两个坑组好头之后紧接着就是校验和。pcap_sendpacket只管发送不帮你算 IP 头校验和也不帮你算 UDP 校验和。IP 头校验和相对简单只对 20 字节 IP 头做反码求和UDP 校验和则要带上 12 字节的伪头部这 12 字节包括源 IP、目的 IP、协议号和 UDP 长度很多初学组包的人会漏掉它结果就是 Wireshark 里一直报 checksum 错误。// 通用 16 位反码校验和按大端顺序逐 16bit 累加 unsigned short checksum(unsigned char *buf, int nbytes) { unsigned long sum 0; int i; for (i 0; i nbytes - 1; i 2) { sum (buf[i] 8) | buf[i 1]; } if (i nbytes) { sum buf[i] 8; } while (sum 16) { sum (sum 0xFFFF) (sum 16); } return (unsigned short)(~sum 0xFFFF); }这个函数把缓冲区按大端解释成 16 位整数做带进位的累加最后把高 16 位折回低 16 位再取反。IP 头校验和调用一次传入的就是 IP 头起始地址和 20 字节长度UDP 校验和则要先在临时缓冲区里拼好「伪头部 UDP 头 载荷」再整体计算。unsigned char pkt[64 1024]; // 以太网头 IP 头 UDP 头 载荷上限 int payload_len (int)strlen(payload); int pkt_len 14 20 8 payload_len; // 填充以太网头 unsigned char dst_mac[6] {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; unsigned char src_mac[6] {0x00, 0x11, 0x22, 0x33, 0x44, 0x55}; memcpy(pkt, dst_mac, 6); memcpy(pkt 6, src_mac, 6); *(unsigned short *)(pkt 12) htons(0x0800); // 填充 IP 头 ip_hdr_t *ip (ip_hdr_t *)(pkt 14); ip-ver_ihl 0x45; ip-tos 0; ip-total_len htons((unsigned short)(20 8 payload_len)); ip-id htons(0x1234); ip-frag_off htons(0x0000); ip-ttl 64; ip-protocol 17; // UDP ip-checksum 0; ip-src_addr inet_addr(192.168.1.100); ip-dst_addr inet_addr(192.168.1.200); ip-checksum checksum((unsigned char *)ip, 20); // 填充 UDP 头 udp_hdr_t *udp (udp_hdr_t *)(pkt 14 20); udp-src_port htons(12345); udp-dst_port htons(9999); udp-length htons((unsigned short)(8 payload_len)); udp-checksum 0; memcpy(pkt 14 20 8, payload, payload_len); // 计算 UDP 校验和伪头部 12 字节 UDP 头 载荷 unsigned char tmp[12 8 1024]; memset(tmp, 0, sizeof(tmp)); memcpy(tmp, ip-src_addr, 4); // 伪头部源 IP直接用已经填好的网络序值 memcpy(tmp 4, ip-dst_addr, 4); // 伪头部目的 IP tmp[8] 0; tmp[9] 17; // 协议号 tmp[10] (unsigned char)((8 payload_len) 8); tmp[11] (unsigned char)(8 payload_len); memcpy(tmp 12, udp, 8); // 复制 UDP 头 memcpy(tmp 20, payload, payload_len); udp-checksum checksum(tmp, 12 8 payload_len);这段代码有几处值得盯住。第一计算 UDP 校验和时udp-checksum必须先置零拿一个留有旧值的头去算结果永远是错的。第二tmp数组的头部 12 字节就是伪头部它的字节序必须和 IP 头里的地址字节序完全一致所以直接从ip-src_addr内存里复制而不是再调一次inet_addr。第三pkt_len算的是实际填充长度后续pcap_sendpacket用的是这个值不是数组容量。3.4 发送循环与时间戳文件pcap_sendpacket 的参数和后置处理报文组装完毕剩下就是发送。pcap_sendpacket接受三个参数打开的pcap_t句柄、帧缓冲区指针、帧长度返回值是 0 表示成功-1 表示失败失败原因可以用pcap_geterr(handle)拉出来看。int sent_count 0; int target_count 1000; for (int i 0; i target_count; i) { if (pcap_sendpacket(handle, pkt, pkt_len) ! 0) { fprintf(stderr, send error: %s\n, pcap_geterr(handle)); break; } sent_count; Sleep(10); // 简单限速约 100 包/秒避免瞬间把网卡队列打满 } printf(sent %d packets, each %d bytes\n, sent_count, pkt_len);发包速率在这里是可以用Sleep的毫秒数粗调的Sleep(10)大约是每秒 100 包Sleep(1)理论上能到每秒上千包但抖动很大。至于压缩包里那串时间戳命名的文件我倾向于认为是这个工程在运行调试阶段输出的日志或者报文样本它不影响主逻辑如果你在包里看到.c源文件旁边有类似send.log的文件打开看一眼数据结构就能确认。真正要关心的只有发送计数和pcap_geterr的输出。4. 编译与运行MinGW 环境下把 WinPcap 发包程序跑起来4.1 环境准备驱动、开发者包和 NPF 服务三件事运行 WinPcap 程序之前机器上必须先装好 WinPcap 驱动否则打开设备直接失败。官方最后版本是 4.1.3安装完成后建议顺手确认一下 NPF 服务状态在管理员 cmd 里执行net start npf如果服务已经是运行状态会有「请求的服务已经启动」的提示。Windows 10/11 上驱动签名校验比较严装老版本容易失败这时更推荐装 Npcap并且在安装向导里勾选 WinPcap API 兼容模式这样既有 WinPcap 的函数接口驱动签名又能通过新系统的校验后面的源码不用改。编译环节需要一份 WinPcap 开发者包 WpdPack解压后里面有 include 和 lib 两个目录。用 MinGW 的时候头文件路径指到WpdPack\Include库路径指到放libwpcap.a和libpacket.a的位置。这个源码包既然自带了.a文件说明作者默认走的就是 MinGW 路线省去了用 reimp 工具转换.lib格式的那一步。4.2 编译命令与链接参数库顺序、ws2_32 依赖和常见报错假设我把包解压到D:\winpcap-udp-test源码文件叫udp_test.c编译命令大概是这个形态gcc -o udp_test.exe udp_test.c \ -I D:\winpcap-udp-test\include \ -L D:\winpcap-udp-test\lib \ -lwpcap -lpacket -lws2_32逐项说下参数含义。-I告诉编译器去哪找pcap.h-L告诉链接器去哪找以-l开头的库文件-lwpcap对应libwpcap.a-lpacket对应libpacket.a。-lws2_32是为了让inet_addr这类 Winsock 函数能链接上很多人在这里踩坑因为pcap.h内部会引用 Winsock 的类型定义不加这个库链接阶段会冒出一堆undefined reference to inet_addr之类的错误。库的顺序在 MinGW 命令行里是个隐藏规则。-lwpcap -lpacket必须放在udp_test.c后面源文件、库从左到右解析符号库放前面会导致pcap_open_live等符号在解析时还没被引用翻车率极高。如果编译报undefined reference to pcap_open_live优先检查库顺序其次检查-L路径是否真的指向包含libwpcap.a的目录。4.3 运行验证用 Wireshark 确认每一个头字段跑起来之后不能只看控制台输出就完事我习惯同时开 Wireshark 在发送网卡上抓包显示过滤器写udp ip.src 192.168.1.100 udp.srcport 12345这样能一屏确认四件事以太网头目的 MAC 是不是你要的IP 头里的源地址和总长度对不对UDP 头的端口和校验和有没有标红载荷内容是不是原始字节。Wireshark 里校验和字段如果显示0x0000且没有报错多半是 UDP 校验和被算成了 0实际很多接收端会忽略这个字段但严谨的测试场景里还是应该按前面 3.3 节的逻辑把校验和算出来。还有一个我反复强调的细节WinPcap 是直接操作链路层的如果目的 MAC 填的是ff:ff:ff:ff:ff:ff这个帧会广播到整个局域网所有机器都会在网卡层收到一个和自己无关的 UDP 包。做内网测试时我一般会先把目的 MAC 填成目标机器的真实 MAC用arp -a查一下就有避免误打扰别的设备。5. 避坑指南安装失败、NPF 服务异常与五个高频翻车点5.1 WinPcap 安装中途失败装完依然报驱动错误现象安装向导走到一半弹出错误提示安装失败装完之后运行程序pcap_open_live返回The specified device could not be opened。原因绝大多数是旧版本残留或安全软件拦截了 NPF 驱动文件。WinPcap 4.1.3 的驱动在 Windows 10/11 上还会碰到签名校验问题安装包没有对应的 WHQL 签名系统直接拒载。解决先把旧版本从控制面板卸载干净重启一次再用管理员身份运行安装包安全软件临时退出。如果系统是 Win10 1803 之后的版本直接换 Npcap 并勾选 WinPcap API 兼容模式这是最省事的路。装 Vivado 这类内嵌 WinPcap 依赖的工具时遇到同样的安装失败也按这个流程处理。5.2 打开设备失败服务列表里找不到 NPF现象程序编译链接都正常一运行pcap_open_live就报Error opening adapter, 或者提示npf.sys没有被加载。原因WinPcap 的 NPF 设备驱动不是一个开机自启的 Windows 服务偶尔会被系统优化工具或安全软件禁用也有一些精简版系统直接没放驱动文件。解决管理员打开 cmd执行sc query npf看服务状态如果是STOPPED或DISABLED执行net start npf启动如果sc query npf报不存在说明驱动没装上回到上一条重装。Npcap 环境下对应的服务名是npcap命令照改即可。5.3 MinGW 链接报 undefined reference库顺序背锅现象gcc 命令执行完一屏错误全是undefined reference to pcap_open_live、undefined reference to pcap_findalldevs但头文件明明能找到。原因两种可能。第一是库顺序问题-lwpcap -lpacket被放在了udp_test.c之前GNU 链接器从左到右解析符号还没被引用时库里的目标文件不会进输出等源文件需要符号时已经来不及了。第二是-L路径指到了 MSVC 的 lib 目录那里放的是wpcap.libMinGW 的链接器识别不了这种 PE 格式导入库。解决把-lwpcap -lpacket -lws2_32统一放到命令行最末-L明确指向包含libwpcap.a的目录。如果只有.lib没有.a用 MinGW 的 reimp 工具转一下或者干脆把开发者包里两个.lib和这个源码包的.a对比一下确认文件格式一致再编译。5.4 有线网卡正常无线网卡上收不到自己发的包现象同样一份源码插网线发包 Wireshark 能抓到切到 WiFi 网卡后抓不到自己的包也不见对端回复。原因无线网卡驱动对混杂模式的支持普遍比有线网卡差很多 WiFi 驱动根本不把「自己发出去的帧」回交给抓包层另外 WiFi 链路上的封装是 802.11 帧头不是标准以太网头 14 字节手工组的 IP 包直接发到 WiFi 网卡上驱动和 AP 都可能把它当成畸形帧丢掉。解决测试优先选有线网卡。如果只能在 WiFi 环境里跑用pcap_findalldevs把设备名列表打出来确认选择的是物理无线网卡而不是适配器同时把目的 MAC 填成 AP 的 MAC否则组播和广播帧在无线网络上很容易被 AP 策略过滤。虚拟机里的用户注意把网卡设为桥接模式NAT 模式下链路层行为是被虚拟化层改写过的不适合验证原始报文。5.5 对端收到了包但 Wireshark 报校验和错误或分片异常现象包是发出去了目标机器也能收到 UDP 数据但抓包软件里 IP 头或 UDP 头显示校验和错误checksum offload 除外或者载荷被拆成了一堆分片。原因校验和算错或没算常见漏掉 UDP 伪头部分片异常则是frag_off字段没填对或者声明pkt数组时把 IP 头的total_len写成了固定值导致实际发送长度和头里声明不一致。解决组包后先别急着发把pkt_len和ip-total_len的值打印出来对一眼再开 Wireshark 抓一个包看专家信息。IP 头校验和错误优先检查checksum()的字节序解释UDP 校验和错误优先检查伪头部有没有拼对。想绕过校验和的验证阶段Wireshark 设置里可以临时关闭校验和校验但真正测试设备时还是要算对因为不少 Linux 协议栈会直接丢弃校验和错误的 UDP 报文。6. 进阶改造从示例发包器变成可限速、可改 IP 头的打流工具把示例跑通之后最常见的下一步是把它改成一个受控的 UDP 打流工具。第一个要动的是发包速率Sleep(10)的粗粒度限速只能到 100 包/秒左右想精确压到目标速率我一般会把Sleep换成QueryPerformanceCounter做微秒级循环或者在每包之间用usleep()调整到微秒量级。配合iperf3 -u做对照测试能看出同一负载下普通协议栈发包和 WinPcap 直发在延迟上的差异——这也是用 WinPcap 做压力测试最常被问到的点。第二个要动的是 IP 头字段。把ttl改成 1就能用来探测交换机对超时 TTL 报文的处理行为把tos改成特定值可以模拟 QoS 标记流量把frag_off填入分片标志和片偏移就能构造 IP 分片报文验证目标设备的组包能力。改完任何一个字段都要用 Wireshark 的显示过滤器重新确认tcpdump -i eth0 udp -XX在 Linux 侧抓包也行Windows 下用 Wireshark 的udp ip.ttl 1过滤就能快速定位。第三个建议是加一个简单的 ARP 存活检查逻辑。WinPcap 手填目的 MAC如果对端换了网卡或者换了网关MAC 变成旧的包就会消失在局域网里。我习惯在发送循环开始前先ping一下目标地址刷新 ARP 缓存再读一次arp -a的解析结果把 MAC 填到帧头里。有一次我贪快没做这个检查拿着旧 MAC 地址发了一千多个包对端一个都没收到Wireshark 里还显示重传白白浪费了一下午。从那以后我每回跑这类发包程序都会先开 Wireshark 确认头字段再确认 ARP 解析结果最后才开始批量打流。希望帮到你。本文还有配套的精品资源点击获取
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

万物演化论21(第六章) 房子到底是资产、负债,还是家庭系统中的一个节点? 2026/9/28 4:33:41

万物演化论21(第六章) 房子到底是资产、负债,还是家庭系统中的一个节点?

21|房子到底是资产、负债,还是家庭系统中的一个节点? 前面两章,我们连续讨论了两个问题。 19|家庭资产配置,本质上也是一场长期进化游戏 我们开始意识到:家庭财富不是一堆孤立的资产&#xf…

阅读更多 →
FreeFileSync 14.12 → Windows (MinGW UCRT64) 版本编译移植状态 2026/9/28 4:33:40

FreeFileSync 14.12 → Windows (MinGW UCRT64) 版本编译移植状态

FreeFileSync 14.12 → Windows (MinGW UCRT64) 版本编译移植状态 结论 可以编译成 Windows 版本。 截至 2025-06,全部 87 个源文件通过 Windows (MinGW UCRT64 / GCC) 语法检查: zen/ 平台层 21/21 ✅应用层(FreeFileSync/Source libcurl …

阅读更多 →
2026国产OpenClaw同款平替全景对比:TaoToken统一Key接入飞书/微信Agent的配置与踩坑指南 2026/9/28 4:33:34

2026国产OpenClaw同款平替全景对比:TaoToken统一Key接入飞书/微信Agent的配置与踩坑指南

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

阅读更多 →
TaoToken 配 Hermes:Windows 本地部署安装包与 config.toml 骨架 2026/9/28 4:33:34

TaoToken 配 Hermes:Windows 本地部署安装包与 config.toml 骨架

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

阅读更多 →
ABAP 里没有 HDLC,但可以接住 HDLC,从数据链路层协议到 SAP 设备集成的完整设计 2026/9/28 4:33:34

ABAP 里没有 HDLC,但可以接住 HDLC,从数据链路层协议到 SAP 设备集成的完整设计

今天正在讨论的这个问题很有代表性。前面研究计算机网络时会碰到 HDLC,回到 SAP 开发环境以后,很自然会产生一个联想,ABAP 里面有没有类似 HDLC 的东西,能不能像处理 HTTP、RFC、OData 一样直接处理 HDLC 帧。 答案需要分成两个层次来看。 如果问的是 ABAP 平台有没有一个…

阅读更多 →
JLink在IAR下连不上的三大高频问题:驱动兼容、调试断连与版本选择 2026/9/28 4:33:15

JLink在IAR下连不上的三大高频问题:驱动兼容、调试断连与版本选择

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

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉