如果你在招聘网站上翻过网络开发、嵌入式网络或者协议栈相关的岗位,大概率见过"熟悉 TCP/IP 协议栈实现"这条要求。多数人学网络是自上而下的:先背三次握手、四次挥手,再记住各种状态机,真到要看一眼协议栈代码或者自己动手改一处收发逻辑的时候,还是发懵。李述铜这套课走的是另一条路——从零开始,一行一行把 TCP/IP 协议栈写出来。它值不值得花时间,取决于你想解决的是哪类问题。
这门课解决的是什么场景
它不是教你配路由器、也不是讲怎么调 Linux 内核参数。课程面向的是"想真正看懂网络协议内部怎么运转"的人:数据包从网卡进来之后,链路层怎么解帧、ARP 怎么找下一跳、IP 怎么分片重组、TCP 怎么维护收发窗口和重传定时器、socket 接口下面到底压着哪些状态。这些内容平时被操作系统封装得很好,你调 API 就能用,但一旦遇到性能瓶颈、异常断连、粘包拆包争议,或者面试被追问到实现细节,封装的便利就变成了盲区。课程的价值就在于把这层封装拆开,让你自己把逻辑搭一遍。
学完能做到什么程度
按课程推进的节奏,走完之后你手上会有一个能跑起来的、自己写的协议栈实现,具备基本的分层结构和收发能力,而不是停留在画架构图的层面。具体一点说:能独立处理以太网帧的收发、能实现 IP 层的寻址与转发逻辑、能把 UDP 和 TCP 的基本流程跑通,并对 TCP 的连接管理、确认重传、流量控制这些机制有自己的代码级理解。这个结果对两类人有用——一类是做嵌入式或网络中间件、需要接触协议栈源码的开发者;一类是准备网络方向面试、想用一个能讲清楚细节的项目替代背八股的求职者。它不会直接让你变成内核网络专家,但能把你从"只会用"推到"看得懂、改得动"。
资料适合什么基础
这不是零基础入门课。学之前至少要满足两点:一是 C 语言能读懂指针、结构体、内存操作,因为协议栈实现里大量涉及缓冲区管理和字节序处理;二是对计算机网络有概念性的认识,知道 IP、端口、MAC 地址大概是什么。如果这两条都缺,直接上手会很吃力,建议先把 C 和网络基础补一补再回来。反过来,如果你已经写过 C 项目、也背过网络八股,这门课正好能把那些零散的知识点串成一条完整的实现链。
怎么用这套资料效率更高
- 按课程推进顺序走,不要跳着看。协议栈是层层依赖的,链路层没搞明白就去看 TCP 状态机,等于白看。
- 不要只看不写。边看边跟着敲,遇到跑不通的地方先自己查,实在卡住再回头对照讲解,这个过程本身就是课程最值钱的部分。
- 每完成一个模块,自己画一张数据流向图:一个包从进入到出去,经过了哪些函数、改了哪些字段。画得出来才算真懂。
- 学完后整理一份实现笔记,把关键数据结构和状态转换记下来。面试或复盘时,这份笔记比任何证书都更能说明问题。
总的来说,这是一门偏硬核、需要动手投入的课。如果你只是想拿个证、刷个简历关键词,它可能不是最省事的选择;但如果你确实想搞明白网络协议底层怎么运转,愿意花时间把代码敲一遍,它能给你的东西比一堆概念课扎实得多。判断标准很简单:你愿不愿意为"看懂一行协议栈代码"这件事,付出几十个小时的动手时间。
课程目录
第01章 课程概述 001.第00.00 课程特点.mp4 002.第01.01 课程介绍.mp4 003.第01.02 资料下载.mp4 005.第01.03 运行效果演示.mp4 第02章 开发环境搭建 001.第02.01 开发环境概述.mp4 002.第02.02 windows开发环境配置.mp4 003.第02.03 mac开发环境搭建.mp4 004.第02.05 工程配置详解.mp4 第03章 基本概念和原理 001.第03.00 基本概念和原理.mp4 002.第03.01 向网络上发送数据包.mp4 003.第03.02 接受数据包修改并发回.mp4 004.第03.03 创建线程(1).mp4 005.第03.03 创建线程(2).mp4 006.第03.04 利用计数信号量同步线程.mp4 007.第03.05 线程间的资源访问控制.mp4 008.第03.06 线程间的资源访问控制实例(1)- 循环缓存.mp4 009.第03.06 线程间的资源访问控制实例(2)- 控制读速率.mp4 010.第03.06 线程间的资源访问控制实例(3)- 控制写速率.mp4 011.第03.09 利用套接字设计客户机(1).mp4 012.第03.09 利用套接字设计客户机(2).mp4 013.第03.10 利用套接字设计服务器.mp4 014.第03.11 tcpip体系结构简介.mp4 第04章 整体结构设计 001.第04.00 整体软件结构设计.mp4 002.第04.01 协议栈的初始化.mp4 003.第04.02 添加核心工作线程.mp4 004.第04.03 创建数据包收发线程.mp4 第05章 调试信息输出 001.第05.01 基本调试信息输出.mp4 002.第05.02 给调试输出增加颜色.mp4 003.第05.03 按不同等级输出信息.mp4 004.第05.04增加assert断言.mp4 第06章 设计通用的链表结构 001.第06.00 通用链表简介.mp4 002.第06.01 创建结点结构.mp4 003.第06.02 创建链表结构.mp4 004.第06.03 头部插入结点.mp4 005.第06.04 遍历链表.mp4 006.第06.06 删除头部结点.mp4 007.第06.06尾部插入结点.mp4 008.第06.07 插入到指定结点之后.mp4 第07章 定长内存块管理 001.第07.00 协议栈中的存储管理问题.mp4 002.第07.01 创建内存块管理器结构.mp4 003.第07.02 添加锁结构.mp4 004.第07.03 建立内存块链.mp4 005.第07.04 分配内存块.mp4 006.第07.05 释放内存块.mp4 第08章 定长消息队列的实现 001.第08.00 定长消息队列简介.mp4 002.第08.01 创建定长消息队列结构.mp4 003.第08.02 初始化核心线程的消息通信.mp4 004.第08.03 向工作线程发送消息.mp4 005.第08.04接受网卡线程发来的消息.mp4 006.第08.05 销毁消息队列.mp4 第09章 网络数据包结构设计 001.第09.00 数据包结构设计简介.mp4 002.第09.01 添加数据包结构.mp4 003.第09.02 分配块链.mp4 004.第09.03 分配指定大小的数据包.mp4 005.第09.04 显示数据包信息.mp4 006.第09.05 释放数据包.mp4 007.第09.06 添加连续包头.mp4 008.第09.07 移除包头.mp4 009.第09.08 添加非连续包头.mp4 010.第09.09 调整包大小(1) – 包的扩大.mp4 011.第09.09 调整包大小(2) – 包的扩大.mp4 012.第09.10 合并两个包.mp4 013.第09.11 调整包头的连续性.mp4 014.第09.12 增加包访问功能.mp4 015.第09.13 写数据包.mp4 016.第09.14 读数据包.mp4 017.第09.15 定位数据包.mp4 018.第09.16 数据包的拷贝.mp4 019.第09.17 填充数据包.mp4 020.第09.18 增加其它支持函数.mp4 第10章 网络接口层设计 001.第10.00 网络接口的设计规划.mp4 002.第10.01 添加网络接口结构.mp4 002.第10.01 添加网络接口结构_20240513222424.pptx.mp4 003.第10.02 初始化网络接口层.mp4 004.第10.03 打开网络接口.mp4 005.第10.04 添加环回接口.mp4 006.第10.05 将地址串转换为ip地址.mp4 007.第10.06 设置网络接口的地址.mp4 008.第10.07 激活环回接口.mp4 009.第10.08 显示网络接口列表.mp4 010.第10.09 关闭和设置缺省的网络接口.mp4 011.第10.10 增加数据包队列的写入和读取.mp4 012.第10.11 添加数据包发送接口.mp4 第11章 支持以太网协议 001.第11.00 以太网协议设计简介.mp4 002.第11.01 打开物理网络接口.mp4 003.第11.02 接收数据并发给工作线程.mp4 004.第11.03 将数据通过网络接口发出去.mp4 005.第11.04 添加链路层接口.mp4 006.第11.05 添加以太网接口.mp4 007.第11.06 添加以太网包结构定义.mp4 008.第11.07 网络大小端转换(1)-原理介绍.mp4 009.第11.07 网络大小端转换(2)- 转换接口.mp4 010.第11.07 网络大小端转换(3)- 检查大小端.mp4 011.第11.08 以太网输入包的处理.mp4 012.第11.09 显示以太网包结构.mp4 013.第11.10 输出以太网数据包.mp4 第12章 定时器的实现 001.第12.00 定时器设计简介.mp4 002.第12.01 添加定时器结构.mp4 003.第12.02 增加定时器测试代码.mp4 004.第12.03 插入定时器(简单方法).mp4 005.第12.04 插入定时器(升序方法).mp4 006.第12.05移除定时器.mp4 007.第12.06 扫描定时器列表.mp4 008.第12.07 让工作线程处理定时事件.mp4 第13章 支持arp协议 001.第13.00 arp协议简介.mp4 002.第13.01 向指定ip地址发送数据.mp4 003.第13.02 初始化arp模块.mp4 004.第13.03 发送arp请求.mp4 005.第13.04 生成无回报()arp.mp4 006.第13.05 获取arp输入包.mp4 007.第13.06 响应发来的arp请求.mp4 008.第13.07 显示arp包结构和缓存表.mp4 009.第13.08 分配和释放缓存表项.mp4 010.第13.09 查找和插入表项.mp4 011.第13.10 解析ip地址并发送包.mp4 012.第13.11 给缓存表项增加超时重新请求.mp4 013.第13.12 清空arp表和查找arp表.mp4 第14章 初步支持ip协议 001.第14.00 ip协议简介.mp4 002.第14.01 添加ip数据报头.mp4 003.第14.02 接收输入的ip数据报.mp4 004.第14.03 ip数据报的预处理检查(1).mp4 005.第14.03 ip数据报的预处理检查(2).mp4 006.第14.04 使用校验和检查包头正确性.mp4 007.第14.05 ip数据报分解处理.mp4 008.第14.06 显示ip包内容.mp4 009.第14.07 发送ip数据报.mp4 010.第14.08 增加ip包发送检验和计算.mp4 第15章 支持icmp协议 001.第15.00 icmp协议简介.mp4 002.第15.01 icmp模块初始化.mp4 003.第15.02 icmp输入处理.mp4 004.第15.03 响应ping请求.mp4 005.第15.04 用ip包更新arp表.mp4 006.第15.05 报告端口不可达.mp4 第16章 ip数据报的分片与重组 001.第16.00 ip分片与重组介绍.mp4 002.第16.01 分片与重组的初始化.mp4 003.第16.02 分片结构的分配与释放.mp4 004.第16.03 分片的查找与添加.mp4 005.第16.04 显示分片列表.mp4 006.第16.05 插入分片.mp4 007.第16.06 数据报分片的重组.mp4 第17章 设计自己的ping命令 001.第17.00 ping程序实现原理.mp4 002.第17.01 添加ping结构与接口.mp4 003.第17.02 实现ping的发送及响应.mp4 004.第17.03 实现ping的响应结果输出.mp4 005.第17.04 增加超时和命令行调用.mp4 第18章 原始套接字 raw socket接口实现 001.第18.00 socket接口设计结构简介.mp4 002.第18.01 请求核心工作线程执行功能函数.mp4 003.第18.02 发送消息请求执行功能.mp4 004.第18.03 定义自己的地址转换函数接口.mp4 005.第18.04 实现自己的地址转换函数.mp4 006.第18.05 定义socket接口.mp4 007.第18.06 分配socket结构.mp4 008.第18.07 发消息给工作线程分配socket结构.mp4 009.第18.08 sock结构定义及初始化.mp4 010.第18.09 建立raw结构.mp4 011.第18.10 创建raw结构块.mp4 012.第18.11 初始化数据发送接口.mp4 013.第18.12 将数据包发送出去.mp4 014.第18.13 初始化数据包接收.mp4 015.第18.14 添加sock等待接口.mp4 016.第18.15 实现各种等待接口.mp4 017.第18.16 初始化sock等待结构.mp4 018.第18.17 让接收能够等待.mp4 019.第18.18 添加超时设置接口.mp4 020.第18.19 开启读取超时.mp4 021.第18.20 ip数据包输入处理.mp4 022.第18.21 实现对ping的响应.mp4 023.第18.22 添加close接口.mp4 024.第18.23 实现raw接口的关闭.mp4 第19章 允许通过路由访问internet 001.第19.00 访问外部网络的原理.mp4 002.第19.01 设计基础的路由表结构.mp4 003.第19.02 添加路由表项.mp4 004.第19.03 删除路由.mp4 005.第19.04 设置缺省路由.mp4 006.第19.05 从路由表中找到合适的表项.mp4 007.第19.06 通过路由器将数据包发往外部.mp4 第20章 支持udp协议 001.第20.00 udp协议简介.mp4 002.第20.01 创建udp客户端.mp4 003.第20.02 创建udp回显服务器.mp4 004.第20.03 udp模块初始化.mp4 005.第20.04 创建udp套接字.mp4 006.第20.05 udp数据的发送处理.mp4 007.第20.06 动态分配端口.mp4 008.第20.07 实现udp数据的发送.mp4 009.第20.08 计算伪校验和.mp4 010.第20.09 udp输入的处理(1).mp4 011.第20.10 udp输入的处理(2).mp4 012.第20.11 udp数据读取的实现.mp4 013.第20.12 关闭udp套接字.mp4 014.第20.13 增加connect接口(1).mp4 015.第20.13 增加connect接口(2).mp4 016.第20.13 增加connect接口(3).mp4 017.第20.14 增加send接口(1).mp4 018.第20.14 增加send接口(2).mp4 019.第20.17 增加recv接口(1).mp4 020.第20.18 增加recv接口(2).mp4 021.第20.19 增加bind接口(1).mp4 022.第20.20 增加bind接口(2).mp4 023.第20.21 让原始套接字支持connectrecvsend.mp4 024.第20.22 udp协议设计总结.mp4 第21章 tcp协议之建立基本的链接 001.第21.00 tcp连接管理简介.mp4 002.第21.00 tcp协议课程规划.mp4 003.第21.01 tcp协议初始化.mp4 004.第21.02 创建tcp套接字.mp4 005.第21.03 接收输入的tcp包.mp4 006.第21.04 发送reset复位包(1).mp4 007.第21.04 发送reset复位包(2).mp4 008.第21.05 几个tcp调试函数.mp4 009.第21.06 增加connectclose回调函数.mp4 010.第21.07 分配端口及检查连接的存在性.mp4 011.第21.08 添加connect等待结构.mp4 012.第21.09 收发窗口及序号初始化.mp4 013.第21.10 发送syn报文.mp4 014.第21.11 设置tcp状态.mp4 015.第21.12 寻找合适的tcp控制块.mp4 016.第21.13 添加输入状态处理函数.mp4 017.第21.14 响应syn_ack报文(1)-终止连接.mp4 018.第21.14 响应syn_ack报文(2)-更新序号值.mp4 019.第21.15 从syn_sent进入established.mp4 020.第21.16 从established进入close-wait.mp4 021.第21.17 从close_wait进入last_ack.mp4 022.第21.18 从last_ack进入closed.mp4 023.第21.19 主动close进入fin_wait_2.mp4 024.第21.20 从fin_wait_2进入time_wait.mp4 025.第21.21 time_wait输入处理.mp4 026.第21.22 同时关闭,进入closing(1).mp4 027.第21.22 同时关闭,进入closing(2).mp4 028.第21.23 closed状态处理及连接总结.mp4 第22章 tcp数据传输及滑动窗口算法 001.第22.00 tcp数据发送介绍.mp4 002.第22.01 初始化发送缓存.mp4 003.第22.02 添加tcp发送的支持.mp4 004.第22.03 将数据写入发送缓存.mp4 005.第22.04 将部分数据发送出去.mp4 006.第22.05 发送全部数据到对方.mp4 007.第22.06 读取tcp选项(mss).mp4 008.第22.07 tcp数据分段发送.mp4 009.第22.08 tcp数据发送总结(1).mp4 010.第22.08 tcp数据发送总结(2).mp4 011.第22.09 添加接收缓存及接收介绍.mp4 012.第22.10 添加下载测试代码.mp4 013.第22.11 增加tcp读取函数.mp4 014.第22.12 往接收缓存中写数据.mp4 015.第22.13 将数据包中的数据写入缓存.mp4 016.第22.14 从接收缓存读取数据(1).mp4 017.第22.14 从接收缓存读取数据(2).mp4 018.第22.15 半关闭时接收返回eof.mp4 019.第22.16 连接时写入选项mss.mp4 020.第22.17 通知对方自己的接收窗口大小.mp4 021.第22.18 检查序号的正确性(1).mp4 022.第22.18 检查序号的正确性(2).mp4 023.第22.19 fin与数据处理的先后顺序.mp4 024.第22.20 tcp数据通信总结.mp4 第23章 tcp保活机制的实现 001.第23.00 tcp保活机制简介.mp4 002.第23.01 保活机制的具体功能演示.mp4 003.第23.02 添加setsockopt函数支持.mp4 004.第23.03 定义保活机制相关的变量.mp4 005.第23.04 增加超时处理.mp4 006.第23.05 发送keepalive报文.mp4 第24章 tcp的被动打开实现 001.第24.00 被动打开与服务器运行.mp4 002.第24.01 增加bind_listen_accept调用支持.mp4 003.第24.02 处理listen和accept回调.mp4 004.第24.03 实现tcp的bind调用.mp4 005.第24.04 实现tcp的listen调用.mp4 006.第24.05 实现tcp的accept调用.mp4 007.第24.06 实现tcp_accept.mp4 008.第24.07 listen状态下的输入处理(1).mp4 009.第24.07 listen状态下的输入处理(2).mp4 010.第24.08 syn_recved状态下输入处理.mp4 011.第24.09 强制关闭tcp连接.mp4 012.第24.10 tcp的timewait状态处理.mp4 013.第24.11 一些修修补补.mp4 014.第24.12 tcp补动打开总结.mp4 第25章 dns协议实现 001.第25.00 dns协议及接口简介.mp4 002.第25.01 添加gethostbyname接口.mp4 003.第25.02 实现gethostbyname(1).mp4 004.第25.02 实现gethostbyname(2).mp4 005.第25.03 dns模块初始化.mp4 006.第25.04 允许解析localhost和ip地址.mp4 007.第25.05 允许解析域名地址.mp4 008.第25.06 构造dns请求包(1).mp4 009.第25.06 构造dns请求包(2).mp4 010.第25.08 获取dns响应输入.mp4 011.第25.09 添加请求id的处理.mp4 012.第25.10 响应的基本检查.mp4 013.第25.11 提取ip地址.mp4 014.第25.12 通知应用与列表显示.mp4 015.第25.13 初始化缓存表.mp4 016.第25.14 缓存表的插入、删除与查找.mp4 017.第25.15 刷新dns缓存表.mp4 018.第25.16 多次重试dns请求.mp4 019.第25.17 dns程序设计上的一个问题.mp4 020.第25.18 dns设计总结.mp4 第26章 tcp重时重传处理 001.第26.00 tcp超时重传处理简介.mp4 002.第26.01 增加重传相关数据.mp4 003.第26.02 tcp输出状态机简介.mp4 004.第26.03 添加不同输出状态下的事件处理函数.mp4 005.第26.04 添加连接syn的重传超时处理.mp4 006.第26.05 实现syn的重传.mp4 007.第26.07 继续发送缓存中的数据.mp4 008.第26.07 实现tcp数据的重传.mp4 009.第26.08 tcp协议实现总结.mp4 第27章 移植到x86操作系统 001.第27.00 移植到x86操作系统.mp4 002.第27.01 移植到x86操作系统演示.mp4 003.第27.02 windows网络环境搭建.mp4 004.第27.03 在操作系统中加入工程源码.mp4 005.第27.04 操作系统接口.mp4 006.第27.05 网络初始化.mp4 007.第27.06 增加系统调用.mp4 008.第27.07 调整内存布局.mp4 009.第27.08 rtl8139驱动实现.mp4 010.第27.09 中断锁的处理.mp4 第28章 移植到stm32(arm内核) 001.第28.00 移植到stm32统简介.mp4 002.第28.01 stm32f4移植运行效果演示.mp4 003.第28.02 keil工程源码组织分析.mp4 004.第28.03 利用rtos提供的操作系统接口.mp4 005.第28.04 网络初始化.mp4 006.第28.05 stm32网卡驱动处理.mp4






