<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[wycgi的博客]]></title><description><![CDATA[]]></description><link>https://blog.youkuaiyun.com/wycgi</link><language>zh-cn</language><generator>https://blog.youkuaiyun.com/</generator><copyright><![CDATA[Copyright &copy; wycgi]]></copyright><item><title><![CDATA[【C/C++】从网卡到 socket：一个 DPDK 用户态协议栈的整体架构]]></title><link>https://blog.youkuaiyun.com/wycgi/article/details/163673403</link><guid>https://blog.youkuaiyun.com/wycgi/article/details/163673403</guid><author>wycgi</author><pubDate>Tue, 11 Aug 2026 18:14:27 +0800</pubDate><description><![CDATA[I/O lcore 与协议 lcore 通过全局 ring 交换 mbuf，协议线程再借助每个 socket 的 ring、TCP 缓冲和 eventfd，把结果交给应用。这样一来，KNI 为本机流量和用户态未处理的报文保留内核去向，Netlink 把 Linux 已有的路由控制面结果同步给 DPDK FIB，协议线程负责实际的转发查表。awesome-stack 需要协调的，正是这几种不同的节奏：网卡按批次收发，协议线程按连接维护状态，应用则按 socket 和 epoll 语义工作。]]></description><category></category></item><item><title><![CDATA[【C/C++】手写 DPDK 协议栈（十二）：TCP 并发与自实现 epoll 的就绪事件分发]]></title><link>https://blog.youkuaiyun.com/wycgi/article/details/163279982</link><guid>https://blog.youkuaiyun.com/wycgi/article/details/163279982</guid><author>wycgi</author><pubDate>Tue, 28 Jul 2026 18:23:01 +0800</pubDate><description><![CDATA[DPDK 负责高性能报文收发，TCP 状态机把包转为 socket 数据，epoll 再把 socket 数据转为应用可等待的事件。三层之间通过明确的队列和所有权衔接，才能在并发连接下既快又可维护。它展示了 epoll 的本质：注册表记录“关心什么”，就绪队列记录“现在有什么可处理”，等待者只从就绪队列取事件。使用红黑树查找注册项，使用链表维护 ready list，并分别对树与就绪表设置同步机制。，用于与 Linux 系统调用区分。则要在 FIN、RST、队列错误等状态转移中明确生成，不能凭空假定。]]></description><category></category></item><item><title><![CDATA[【C/C++】手写 DPDK 协议栈（十一）：基于 PPS、SYN 比例和源 IP 熵的 DDoS 检测]]></title><link>https://blog.youkuaiyun.com/wycgi/article/details/163279934</link><guid>https://blog.youkuaiyun.com/wycgi/article/details/163279934</guid><author>wycgi</author><pubDate>Tue, 28 Jul 2026 18:20:20 +0800</pubDate><description><![CDATA[将检测逻辑放在高速包路径中：以一秒为统计窗口，计算包速率、TCP SYN 占比与源 IP 分布的 Shannon 熵。熵检测回答的是“流量分布是否异常”，SYN 比例回答的是“连接意图是否异常”，PPS 回答的是“强度是否异常”。单源或少量源集中时，熵降低。课程代码先将源 IP 做轻量 hash 后映射到 256 个桶，再遍历非零桶累计熵。这里的检测函数只做观察，不应该在数据面直接“一键全丢包”：误报会造成比攻击更严重的业务中断。仅应在明确授权、隔离的靶场执行，绝不能对公网或未授权主机压测。]]></description><category></category></item><item><title><![CDATA[【C/C++】手写 DPDK 协议栈（十）：DPDK 接入 dnspod-sr，实现高性能 DNS UDP 处理]]></title><link>https://blog.youkuaiyun.com/wycgi/article/details/163279783</link><guid>https://blog.youkuaiyun.com/wycgi/article/details/163279783</guid><author>wycgi</author><pubDate>Tue, 28 Jul 2026 18:11:24 +0800</pubDate><description><![CDATA[DPDK DNS 的价值在于把最热的 UDP 接入路径移到用户态，同时复用成熟 DNS 业务处理。设计重点是将原始 DNS payload 和网络返回路径的 peer 元数据一起跨线程传递。保存客户端 MAC、客户端 IP/端口和服务端 IP/端口。DNS payload 本身不含二层地址，因此这份元数据是响应能正确回到客户端的关键。这段失败释放非常重要：ring 满时发送线程还没接管 mbuf，当前函数仍拥有它。起步，避免压测机先耗尽端口、套接字或内存，再逐步提高负载。将高速 UDP 收包与。]]></description><category></category></item><item><title><![CDATA[【C/C++】手写 DPDK 协议栈（九）：KNI 把未接管流量交回 Linux 内核]]></title><link>https://blog.youkuaiyun.com/wycgi/article/details/163279657</link><guid>https://blog.youkuaiyun.com/wycgi/article/details/163279657</guid><author>wycgi</author><pubDate>Tue, 28 Jul 2026 18:03:47 +0800</pubDate><description><![CDATA[它适合原型和兼容场景，但新项目需注意 DPDK 版本对 KNI 的支持状态；KNI 是“选择性接管”的桥梁：加速路径在 DPDK，兼容路径留给成熟的 Linux 协议栈。关键不是把所有包一股脑送 KNI，而是明确分类、所有权和回退策略。的目标不是让 DPDK 处理所有协议，而是把不需要用户态加速的流量交还给 Linux：UDP 等目标流量走 DPDK，其他流量经 KNI 回到内核协议栈。DPDK 绑定物理网卡后，内核不再直接收到该口的包。要持续调用，才能响应内核侧的控制请求。]]></description><category></category></item><item><title><![CDATA[【C/C++】手写 DPDK 协议栈（八）：用五元组 Hash 加速连接定位]]></title><link>https://blog.youkuaiyun.com/wycgi/article/details/163279492</link><guid>https://blog.youkuaiyun.com/wycgi/article/details/163279492</guid><author>wycgi</author><pubDate>Tue, 28 Jul 2026 17:55:49 +0800</pubDate><description><![CDATA[对 TCP 来说，同一监听端口可同时服务大量客户端；只靠目的端口无法区分已建立连接，因此必须把对端 IP/端口加入键。监听 socket 可使用目的 IP、目的端口、协议的较短键，已连接 socket 使用完整五元组。]]></description><category></category></item><item><title><![CDATA[【C/C++】手写 DPDK 协议栈（七）：用 rte_ring 拆出物理层、协议栈层和应用层]]></title><link>https://blog.youkuaiyun.com/wycgi/article/details/163279415</link><guid>https://blog.youkuaiyun.com/wycgi/article/details/163279415</guid><author>wycgi</author><pubDate>Tue, 28 Jul 2026 17:53:28 +0800</pubDate><description><![CDATA[先用 pps、平均/尾延迟、丢包率和队列占用定位瓶颈。三层架构的收益是职责清晰和可独立扩展：协议层不再被应用阻塞，应用不再直接占用 RX 轮询。否则会出现隐蔽的数据竞争。是无锁/低锁环形队列，支持 SP/SC、MP/MC 等生产消费模式。为每个队列明确一条规则：入队成功后由消费者释放，入队失败则由当前线程释放或重试。没有这条规则，队列满时最容易产生泄漏、重复释放或“发送后又释放”的 use-after-free。随着 ARP、UDP、TCP 处理加入同一轮询循环，网卡收发、协议解析和业务逻辑会相互阻塞。]]></description><category></category></item><item><title><![CDATA[【C/C++】手写 DPDK 协议栈（六）：TCP 三次握手、状态机与数据回显]]></title><link>https://blog.youkuaiyun.com/wycgi/article/details/163279195</link><guid>https://blog.youkuaiyun.com/wycgi/article/details/163279195</guid><author>wycgi</author><pubDate>Tue, 28 Jul 2026 17:42:12 +0800</pubDate><description><![CDATA[这个版本适合作为 TCP 状态机起点，但尚未覆盖重传定时器、滑动窗口、乱序重组、拥塞控制、TIME_WAIT 管理、RST、MSS/窗口缩放协商和完整校验。手写 TCP 最有价值的部分不在“拼出一个 SYN+ACK”，而在于把每个输入报文映射为明确状态转移、序列号更新和应用可见事件。在 UDP 的 socket/ring 框架上加入 TCP 状态、序列号、确认号与标志位。数据到达时先排队 ACK，再将 payload 投递给应用，能让“确认网络数据”和“业务处理”解耦。纯 ACK 不消耗序列号。]]></description><category></category></item><item><title><![CDATA[【C/C++】手写 DPDK 协议栈（五）：用 mbuf 实现 UDP 的 bind、recvfrom 与 sendto]]></title><link>https://blog.youkuaiyun.com/wycgi/article/details/163279004</link><guid>https://blog.youkuaiyun.com/wycgi/article/details/163279004</guid><author>wycgi</author><pubDate>Tue, 28 Jul 2026 17:34:40 +0800</pubDate><description><![CDATA[课程实现清楚展示了用户态 UDP 的最小路径，但生产实现还应补上：UDP 长度与 mbuf 边界校验、队列满时的回压策略、IPv4 选项/分片处理、套接字并发保护，以及按 NUMA/lcore 分片的 socket 表。UDP 阶段把协议解析、逻辑 socket、ring 和条件变量串起来：RX 线程负责快，应用线程负责业务。关键点是 socket 层不持有原始 mbuf：协议线程解析后复制应用需要的元数据与负载，随后释放 mbuf。先填字段，将 IP 校验和、UDP 校验和清零，再分别调用。]]></description><category></category></item><item><title><![CDATA[【C/C++】手写 DPDK 协议栈（四）：实现 ICMP Echo Reply，让 ping 通起来]]></title><link>https://blog.youkuaiyun.com/wycgi/article/details/163278532</link><guid>https://blog.youkuaiyun.com/wycgi/article/details/163278532</guid><author>wycgi</author><pubDate>Tue, 28 Jul 2026 17:17:29 +0800</pubDate><description><![CDATA[Echo Request/Reply 是最适合验证三层收发正确性的协议：不需要端口和连接状态，但要求正确交换地址并重算校验和。成功意味着：主机已通过 ARP 找到 DPDK 网卡 MAC，DPDK 正确解析 IPv4/ICMP，且回包的以太网头、IP 头与 ICMP 校验和全部有效。它验证了偏移解析、网络字节序、校验和和回包地址交换，为 UDP、TCP 的组包与分发打下了同一套基础。原地回包可减少一次分配，但一定要在发送前同时交换二层和三层地址，并在所有字段更新完成后重新计算校验和。]]></description><category></category></item><item><title><![CDATA[【C/C++】手写 DPDK 协议栈（三）：ARP 请求识别、应答与 ARP 表]]></title><link>https://blog.youkuaiyun.com/wycgi/article/details/163278072</link><guid>https://blog.youkuaiyun.com/wycgi/article/details/163278072</guid><author>wycgi</author><pubDate>Tue, 28 Jul 2026 17:03:23 +0800</pubDate><description><![CDATA[最容易遗漏的是字节序、仅响应本机目标 IP，以及未命中 ARP 表时不能直接构造单播数据包。实际代码中应保留请求方地址的临时副本再覆盖字段，避免先写后读导致地址丢失。发送方向若找不到目标 MAC，应先广播 ARP Request，缓存或重试原业务包。ARP 正是完成“IP 地址到 MAC 地址”映射的二层协议。，且 ARP 请求的目标 IP 是本机 IP。收到请求后，交换双方 MAC/IP 并把操作码改为应答。，后续 UDP/TCP 模块也复用了 ARP 表和 ARP 组包逻辑。]]></description><category></category></item><item><title><![CDATA[【C/C++】DPDK 基础使用：从 EAL 初始化到 RX/TX 队列收发数据]]></title><link>https://blog.youkuaiyun.com/wycgi/article/details/163277907</link><guid>https://blog.youkuaiyun.com/wycgi/article/details/163277907</guid><author>wycgi</author><pubDate>Tue, 28 Jul 2026 16:57:08 +0800</pubDate><description><![CDATA[本文介绍了DPDK基础使用方法，从EAL初始化到数据包收发流程。核心内容包括：1）初始化顺序必须遵循EAL、内存池、端口配置、队列设置的步骤；2）通过rte_eth_rx_burst接收数据包，利用rte_pktmbuf_mtod解析协议头；3）使用rte_pktmbuf_alloc分配内存并填充数据后，通过rte_eth_tx_burst发送数据包。文章还强调了mbuf管理和协议处理要点，并指出六个关键API构成了DPDK的核心框架，为后续网络协议开发奠定了基础。]]></description><category></category></item><item><title><![CDATA[【C/C++】从零配置 DPDK 实验环境：巨页、VMware 网卡、驱动加载与 PCI 绑定]]></title><link>https://blog.youkuaiyun.com/wycgi/article/details/163277641</link><guid>https://blog.youkuaiyun.com/wycgi/article/details/163277641</guid><author>wycgi</author><pubDate>Tue, 28 Jul 2026 16:46:13 +0800</pubDate><description><![CDATA[环境成功的判据不是“模块已加载”，而是：巨页可用、目标 PCI 被 UIO/VFIO 接管、程序能枚举端口，且宿主机能向该 MAC 发出测试流量。代价是环境必须一次配对：CPU、巨页、IOMMU/驱动和 PCI 网卡缺一不可。页面大小和数量要根据 mbuf 数量、NUMA 和可用内存调整，不能在生产主机上盲目照搬。若接口将由 DPDK 独占，则无需配置 IP。这样主机知道目标 MAC，报文才会被发往被 DPDK 接管的虚拟网卡。网卡通过 DMA 直接读写预分配的大页内存，减少中断、系统调用和数据拷贝。]]></description><category></category></item><item><title><![CDATA[【C/C++】用户态协议栈如何实现 epoll：红黑树、就绪队列和回调通知]]></title><link>https://blog.youkuaiyun.com/wycgi/article/details/162423410</link><guid>https://blog.youkuaiyun.com/wycgi/article/details/162423410</guid><author>wycgi</author><pubDate>Mon, 29 Jun 2026 15:22:36 +0800</pubDate><description><![CDATA[用户态协议栈实现epoll的核心机制 本文介绍了在用户态协议栈中实现epoll功能的三个核心组件： 数据结构设计：使用红黑树(rbr)维护关注集合，链表(rdlist)管理就绪事件，条件变量(cond)实现等待机制。 关键操作流程： nepoll_create创建eventpoll对象并初始化数据结构 nepoll_ctl通过红黑树管理关注的socket描述符 协议栈通过回调函数将就绪事件加入就绪队列并唤醒等待线程 高效通知机制：采用"就绪通知"而非轮询方式，当socket状态变化时主动触发回调，将事件插入]]></description><category></category></item><item><title><![CDATA[【C/C++】从 DPDK 收包到用户态 TCP/IP 协议栈：一个 ustack 示例拆解]]></title><link>https://blog.youkuaiyun.com/wycgi/article/details/162423263</link><guid>https://blog.youkuaiyun.com/wycgi/article/details/162423263</guid><author>wycgi</author><pubDate>Mon, 29 Jun 2026 15:18:58 +0800</pubDate><description><![CDATA[本文介绍了基于DPDK实现用户态TCP/IP协议栈的核心流程。首先明确DPDK并非协议栈，而是绕过内核直接访问网卡的工具箱。文章详细拆解了五个关键环节：(1)DPDK初始化阶段创建内存池和网卡队列；(2)主循环通过ring结构解耦收发包过程；(3)协议分发层处理Ethernet/IPv4/UDP/TCP等协议；(4)UDP报文如何进入应用缓冲区；(5)KNI机制将不处理的数据包交回内核。示例代码展示了如何从DPDK收包到实现用户态协议栈的基本框架，为构建高性能网络应用提供了参考方案。]]></description><category></category></item><item><title><![CDATA[【C/C++】从 setjmp 到 ucontext 再到 hook：C 语言协程是怎么跑起来的？]]></title><link>https://blog.youkuaiyun.com/wycgi/article/details/162349488</link><guid>https://blog.youkuaiyun.com/wycgi/article/details/162349488</guid><author>wycgi</author><pubDate>Fri, 26 Jun 2026 22:10:07 +0800</pubDate><description><![CDATA[网络服务里经常有一个矛盾：课程笔记里对这个问题的概括很直接：
协程要解决的就是这个问题：业务代码看起来像同步代码，底层遇到 IO 不就绪时主动让出 CPU；等 fd 就绪后，调度器再恢复它。所以协程不是为了“炫技式切栈”，而是为高并发 IO 服务：一个函数普通调用时，执行权从调用者进入被调用者；函数返回后，栈帧销毁，不能随便回到中间某一行继续执行。协程不一样。它要支持两个基本动作：课程里列了三种常见实现路线：
这三种方法的核心都一样：保存 CPU 寄存器、栈信息和下一条执行位置；恢复时再把这些状态装回去。先]]></description><category></category></item><item><title><![CDATA[【C/C++】从 POSIX Socket 到 TCP 生命周期：一文理解网络 IO 的核心原理]]></title><link>https://blog.youkuaiyun.com/wycgi/article/details/162339276</link><guid>https://blog.youkuaiyun.com/wycgi/article/details/162339276</guid><author>wycgi</author><pubDate>Fri, 26 Jun 2026 13:48:44 +0800</pubDate><description><![CDATA[文章摘要：理解网络IO核心原理：从POSIX Socket到TCP生命周期 本文系统梳理了C/C++网络编程的核心原理，从POSIX Socket API到TCP连接生命周期管理。主要内容包括：socket()创建文件描述符与TCP控制块，bind()绑定地址端口，listen()准备连接队列，TCP三次握手同步序列号，accept()获取已建立连接，send/recv操作内核缓冲区数据的原理。文章还介绍了epoll+Reactor模式的高效IO多路复用机制，以及边缘触发模式下非阻塞accept的注意事项。]]></description><category></category></item><item><title><![CDATA[【C/C++】C1000K 百万连接测试：Linux 参数、fd 限制和 epoll 压测客户端]]></title><link>https://blog.youkuaiyun.com/wycgi/article/details/162312306</link><guid>https://blog.youkuaiyun.com/wycgi/article/details/162312306</guid><author>wycgi</author><pubDate>Thu, 25 Jun 2026 18:05:36 +0800</pubDate><description><![CDATA[很多人一提到百万连接，第一反应就是epoll。但真正测试时，epoll往往不是第一个瓶颈。README 中整理了一组面向长连接数量测试的参数。它的目标是让系统能维持大量连接，而不是追求高吞吐。]]></description><category></category></item><item><title><![CDATA[【C/C++】C 语言实现 WebSocket：握手、帧解析、掩码和回显]]></title><link>https://blog.youkuaiyun.com/wycgi/article/details/162312022</link><guid>https://blog.youkuaiyun.com/wycgi/article/details/162312022</guid><author>wycgi</author><pubDate>Thu, 25 Jun 2026 17:54:43 +0800</pubDate><description><![CDATA[WebSocket 不是一开始就直接发送二进制帧，它先通过 HTTP 发起升级请求。服务端要读取，按 RFC 6455 的规则生成，再返回。之后这条 TCP 连接才进入 WebSocket 帧通信阶段。项目中的 WebSocket 状态用state == 0state == 1state == 2。]]></description><category></category></item><item><title><![CDATA[【C/C++】用 epoll 写一个 Reactor：连接对象、回调和状态机]]></title><link>https://blog.youkuaiyun.com/wycgi/article/details/162311888</link><guid>https://blog.youkuaiyun.com/wycgi/article/details/162311888</guid><author>wycgi</author><pubDate>Thu, 25 Jun 2026 17:42:31 +0800</pubDate><description><![CDATA[本文介绍了用C/C++基于epoll实现Reactor模式的核心思想，重点分析了连接管理、事件注册和回调机制的设计。Reactor通过分离事件循环和业务处理解决了裸epoll代码臃肿的问题：1) 使用connection结构集中管理连接状态；2) 将epoll_ctl封装为set_event简化操作；3) 通过event_register绑定fd与回调函数；4) 主循环仅负责事件分发。文章通过WebSocket和HTTP文件传输示例，展示了如何利用状态机和读写缓冲区实现分阶段协议处理，特别是处理部分写入等网]]></description><category></category></item></channel></rss>