TCP拥塞控制:慢启动、拥塞避免与BBR算法

引言 在上一篇文章中,我们学习了TCP的流量控制机制(接收方控制发送方,避免接收缓冲区溢出)。今天我们来学习TCP的拥塞控制机制(Congestion Control):发送方感知网络状况,避免网络拥塞。 为什么需要拥塞控制? 流量控制解决了端到端的问题(接收方处理能力) 但网络本身也有容量限制(带宽、路由器缓冲区) 如果所有发送方都全速发送,网络会瘫痪 今天我们来理解: ✅ 慢启动(Slow Start) ✅ 拥塞避免(Congestion Avoidance) ✅ 快速重传(Fast Retransmit) ✅ 快速恢复(Fast Recovery) ✅ Google BBR算法的革新 第一性原理:为什么需要拥塞控制? 问题:网络拥塞 场景:100个客户端同时向服务器发送数据 100个客户端 路由器 服务器 | | | | 每个1Gbps速度发送 | 路由器带宽只有10Gbps | |-------------------------->| | | | 队列满了!丢包! | | | | | 丢包后重传,继续全速发送 | | |-------------------------->| | | | 更加拥塞! | | | 丢包率暴增! | | | | | ❌ 网络瘫痪 | | 拥塞的后果: ❌ 丢包率增加 ❌ 延迟增加(路由器队列排队) ❌ 吞吐量下降(大量重传) ❌ 网络资源浪费 拥塞控制的目标: ...

2025-11-20 · maneng

TCP流量控制:滑动窗口让数据传输更高效

引言 在前面的文章中,我们学习了TCP如何建立连接(三次握手)和断开连接(四次挥手)。今天我们来学习TCP如何在连接建立后高效可靠地传输数据:流量控制机制(Flow Control)。 为什么需要流量控制? 发送方可能发送得很快,接收方可能处理得很慢 如果发送方不控制速度,接收方的缓冲区会溢出,数据丢失 流量控制让接收方告诉发送方:我能接收多少数据 今天我们来理解: ✅ 滑动窗口(Sliding Window)的工作原理 ✅ 接收窗口(rwnd)和发送窗口的关系 ✅ 零窗口问题与窗口探测 ✅ 如何调整TCP窗口大小以提升性能 第一性原理:为什么需要流量控制? 问题:接收方处理不过来 场景:文件传输 发送方(高性能服务器) 接收方(低性能客户端) | | | 发送1GB数据,速度1Gbps | 接收速度只有100Mbps |----------------------------> | 接收缓冲区64KB | | | 继续疯狂发送... | 缓冲区满了! |----------------------------> | ❌ 数据丢失 | | 不同场景的速度差异: 场景 发送方 接收方 问题 服务器 → 客户端 10Gbps网卡 100Mbps网卡 速度差100倍 内存 → 磁盘 内存写入50GB/s 磁盘写入500MB/s 速度差100倍 批量导入 10万条/秒 DB只能处理1万条/秒 处理能力差10倍 流量控制的目标:让发送方的速度匹配接收方的处理能力 滑动窗口:TCP流量控制的核心机制 核心思想 接收方告诉发送方:“我还有X字节的缓冲空间,你最多发送X字节” 接收方 发送方 | | | TCP头部:Window=8192 | |<-------------------------| | | 含义: "我的接收缓冲区还有8192字节空间, 你最多发送8192字节" 接收窗口(rwnd) 接收窗口(Receive Window):接收方在TCP头部的Window字段通告给发送方的值 ...

2025-11-20 · maneng

TCP四次挥手详解:为什么需要四次挥手?

引言 在上一篇文章中,我们理解了TCP如何通过三次握手建立连接。今天我们来学习TCP如何断开连接:四次挥手(Four-Way Handshake)。 为什么需要四次挥手? TCP是全双工通信(双方可以同时发送和接收数据) 断开连接时,双方都要关闭自己的发送通道 一方关闭发送,不代表另一方也要立即关闭 今天我们来理解: ✅ 四次挥手的完整流程 ✅ 为什么需要四次挥手而不是三次? ✅ TIME_WAIT状态为什么要等待2MSL? ✅ CLOSE_WAIT问题的排查与解决 ✅ 连接泄漏的定位方法 四次挥手的完整流程 流程图解 客户端 (Client) 服务器 (Server) | ESTABLISHED | ESTABLISHED | | | [第一次挥手] FIN=1, seq=101 | | 主动关闭 | |----------------------------------->| | FIN_WAIT_1 | 收到FIN | | CLOSE_WAIT(被动关闭) | | | [第二次挥手] ACK=1, ack=102 | |<-----------------------------------| | FIN_WAIT_2 | CLOSE_WAIT | 等待服务器关闭 | (可能继续发送数据) | | | | 应用程序调用close() | [第三次挥手] FIN=1, seq=201 | |<-----------------------------------| | 收到FIN | LAST_ACK | TIME_WAIT | | | | [第四次挥手] ACK=1, ack=202 | |----------------------------------->| | TIME_WAIT(等待2MSL) | 收到ACK | | CLOSED | 2MSL后 | | CLOSED | 详细步骤 第一次挥手:客户端发起关闭 客户端 → 服务器 ...

2025-11-20 · maneng

TCP三次握手详解:为什么是三次而不是两次?

引言 在上一篇文章中,我们理解了传输层的核心使命和TCP/UDP的本质区别。今天我们深入TCP协议的第一个重要机制:三次握手(Three-Way Handshake)。 为什么需要三次握手? TCP是面向连接的协议(像打电话,先拨号建立连接) 在传输数据之前,必须先建立一条可靠的连接 三次握手就是建立连接的过程 今天我们来理解: ✅ 三次握手的完整流程 ✅ 为什么是三次而不是两次或四次? ✅ SYN/ACK标志位的作用 ✅ 半连接队列和全连接队列 ✅ SYN Flood攻击原理与防护 三次握手的完整流程 流程图解 客户端 (Client) 服务器 (Server) | | | [第一次握手] SYN=1, seq=100 | |------------------------------------->| LISTEN状态 | | 收到SYN,进入SYN_RCVD状态 | | | [第二次握手] SYN=1, ACK=1 | | seq=200, ack=101 | |<-------------------------------------| | 收到SYN-ACK,进入ESTABLISHED状态 | | | | [第三次握手] ACK=1, ack=201 | |------------------------------------->| | | 收到ACK,进入ESTABLISHED状态 | | | [连接建立完成,开始传输数据] | |<------------------------------------>| 详细步骤 第一次握手:客户端发送SYN 客户端 → 服务器 ...

2025-11-20 · maneng

传输层的核心使命:端到端通信的守护者

引言 在前面的文章中,我们理解了网络层(IP协议)如何实现主机到主机的通信。但这里有个问题: 一台主机上运行着几十个应用程序(浏览器、微信、游戏、音乐播放器…),当数据包到达这台主机时,网络层该把它交给哪个应用? 这就是传输层要解决的核心问题:端到端通信(进程到进程通信)。 今天我们来理解: ✅ 传输层为什么必须存在? ✅ 端口号如何解决"进程寻址"问题? ✅ Socket是什么?为什么它是网络编程的核心? ✅ TCP和UDP的本质区别是什么? 第一性原理:为什么需要传输层? 问题1:网络层只能送到主机,不能送到进程 想象一个场景: 你的电脑(IP: 192.168.1.100)同时在: - 浏览器访问淘宝(Chrome进程) - 微信聊天(WeChat进程) - 后台下载文件(迅雷进程) - 听音乐(网易云进程) 当一个数据包到达 192.168.1.100 时,网络层只知道这是给这台主机的,但不知道该交给哪个应用程序。 传输层的第一个使命:在网络层"主机到主机"的基础上,实现"进程到进程"的通信。 问题2:不同应用对通信质量有不同要求 HTTP下载文件:要求数据完整,可以慢一点 视频通话:要求实时性,丢几个数据包问题不大 游戏:要求低延迟,偶尔丢包可以接受 文件传输:要求100%可靠,不能有任何错误 传输层的第二个使命:根据应用的不同需求,提供不同的传输服务(可靠的TCP vs 快速的UDP)。 问题3:网络是不可靠的 网络层(IP协议)只负责"尽力而为"地传输数据包,它不保证: ❌ 数据包一定能到达 ❌ 数据包按序到达 ❌ 数据包不重复 ❌ 数据包不损坏 对于需要可靠通信的应用,必须有一层协议来保证这些特性。 传输层的第三个使命:为需要可靠通信的应用提供可靠传输服务(TCP的职责)。 端口号:进程的"身份证" 端口号的设计哲学 核心思想:用一个16位整数(0-65535)唯一标识一台主机上的一个应用程序(准确说是一个进程的通信端点)。 IP地址 → 定位主机(哪台电脑) 端口号 → 定位进程(哪个应用) 完整的通信地址(五元组): 源IP + 源端口 + 目标IP + 目标端口 + 协议类型(TCP/UDP) 端口号的分类 端口范围 名称 用途 示例 0-1023 知名端口(Well-Known Ports) 系统服务和常见应用 HTTP:80, HTTPS:443, SSH:22, MySQL:3306 1024-49151 注册端口(Registered Ports) 用户应用程序 Tomcat:8080, Redis:6379, Nacos:8848 49152-65535 动态端口(Dynamic Ports) 客户端临时使用 客户端发起连接时随机分配 实战案例:查看端口使用情况 场景1:查看当前监听的端口 ...

2025-11-20 · maneng

MAC地址与ARP协议:数据链路层的寻址魔法

引言 上一篇我们学习了IP地址,它是网络层的逻辑地址,用于跨网络寻址。 但你有没有想过一个问题:既然有了IP地址,为什么还需要MAC地址? 这是一个非常好的问题,涉及到网络分层设计的核心思想。 第一性原理:为什么需要两种地址? 问题场景 假设你要给朋友寄一封信: 方案1:只用身份证号 身份证号:320123199001011234 问题:❌ 无法投递(不知道地址在哪里) 方案2:只用门牌号 门牌号:XX街道XX号 问题:❌ 无法确认收件人身份 方案3:身份证号 + 门牌号 身份证号:确认收件人身份 门牌号:确认投递地址 结果:✅ 准确投递 类比理解 概念 现实世界 网络世界 身份标识 身份证号 IP地址 位置标识 门牌号 MAC地址 作用范围 全国唯一 全球唯一(IP) 作用范围 本地唯一 本地唯一(MAC) 是否变化 不变 IP可变 是否变化 可变(搬家) MAC不变 为什么需要两个地址? IP地址(网络层): ✅ 全球唯一(公网IP) ✅ 可路由(根据前缀转发) ✅ 逻辑地址(可变,如DHCP分配) ❌ 无法直接传输(需要知道下一跳的物理地址) MAC地址(数据链路层): ✅ 全球唯一(网卡出厂固化) ✅ 可直接传输(同一网段) ❌ 不可路由(平坦地址空间) ❌ 仅本地有效(跨路由器会被替换) 结论: IP地址:解决"要去哪里"的问题(目的地) MAC地址:解决"怎么去"的问题(下一跳) ARP协议:解决"IP → MAC"的映射问题 MAC地址详解 什么是MAC地址? MAC(Media Access Control)地址:媒体访问控制地址,也叫物理地址或硬件地址。 ...

2025-11-20 · maneng

IP地址与子网划分:网络寻址的艺术

引言 在现实生活中,我们通过地址找到一个人的家: 国家 → 省 → 市 → 区 → 街道 → 门牌号 在网络世界中,我们通过IP地址找到一台计算机: 93.184.216.34 IP地址是网络层最核心的概念之一,理解它对于掌握计算机网络至关重要。 第一性原理:为什么需要IP地址? 问题:如何在全球网络中找到一台计算机? 假设全球有50亿台设备联网,如何唯一标识每一台? 方案1:随机编号 ❌ 无法路由(不知道往哪个方向发送) ❌ 需要全局查找表(太大,无法维护) 方案2:层次化编号(IP地址) ✅ 可以路由(根据前缀决定方向) ✅ 分段查找(路由器只需维护部分信息) ✅ 可扩展(支持更多设备) IP地址的设计哲学 全球唯一性:每个公网IP只能分配给一台设备 层次化结构:网络部分 + 主机部分 可路由性:路由器根据IP前缀转发数据包 IPv4:32位地址 基本格式 二进制表示:11000000.10101000.00000001.01100100 十进制表示:192.168.1.100 十六进制表示:C0.A8.01.64 每个点分十进制数字范围:0-255(2^8 = 256) IPv4地址总数 32位 = 4字节 = 2^32 = 4,294,967,296个地址 约43亿个地址 问题:全球人口超过80亿,IPv4地址不够用! 解决方案: NAT(网络地址转换) 私网IP复用 IPv6(128位地址) 分类地址(历史知识) 早期互联网使用分类地址(Classful Addressing),已淘汰,但需了解: A类地址 格式:0XXXXXXX.XXXXXXXX.XXXXXXXX.XXXXXXXX 范围:1.0.0.0 - 126.255.255.255 网络数:128个(2^7) 每个网络主机数:16,777,214个(2^24 - 2) 用途:超大型网络(如MIT、IBM) B类地址 格式:10XXXXXX.XXXXXXXX.XXXXXXXX.XXXXXXXX 范围:128.0.0.0 - 191.255.255.255 网络数:16,384个(2^14) 每个网络主机数:65,534个(2^16 - 2) 用途:中型网络(如大学、公司) C类地址 格式:110XXXXX.XXXXXXXX.XXXXXXXX.XXXXXXXX 范围:192.0.0.0 - 223.255.255.255 网络数:2,097,152个(2^21) 每个网络主机数:254个(2^8 - 2) 用途:小型网络(如小公司、家庭) D类和E类 D类:224.0.0.0 - 239.255.255.255(多播地址) E类:240.0.0.0 - 255.255.255.255(保留,实验用) 分类地址的问题 浪费严重:B类网络有6.5万个IP,但很多公司只需几千个 不够灵活:只能选择A/B/C三种固定大小 路由表膨胀:互联网路由表越来越大 1993年,CIDR取代了分类地址! ...

2025-11-20 · maneng

数据包的奇幻旅程:从浏览器到服务器

引言 前几篇我们学习了OSI七层模型和TCP/IP四层模型,理解了网络分层的概念。但这些都是抽象的理论。 现在我们要做的是:跟踪一个真实的数据包,看看它如何从你的浏览器,一步步到达目标服务器。 这就像跟踪一封信从投递到收信的完整过程,让我们看看网络世界中数据包的"快递之旅"。 场景设定 假设你在浏览器地址栏输入:http://www.example.com/index.html 并按下回车。 让我们跟随数据包的旅程,看看背后发生了什么! 准备工作:DNS域名解析 在真正发送HTTP请求之前,浏览器需要先知道 www.example.com 的IP地址。 DNS查询过程 1. 浏览器检查缓存 ├─ 浏览器DNS缓存 ├─ 操作系统DNS缓存 └─ hosts文件 2. 如果缓存没有,向DNS服务器查询 ├─ 本地DNS服务器(运营商提供,如8.8.8.8) ├─ 根DNS服务器 ├─ .com顶级域名服务器 └─ example.com权威DNS服务器 3. 获得IP地址:93.184.216.34 DNS查询是一个UDP请求(应用层协议),过程如下: 应用层:DNS查询请求 ↓ 传输层:UDP协议,端口53 ↓ 网络层:IP协议,目标8.8.8.8(Google DNS) ↓ 链路层:以太网帧 ↓ 发送到DNS服务器 DNS响应: 93.184.216.34 现在浏览器知道了目标IP地址,可以发送HTTP请求了! 第1站:应用层 - 浏览器生成HTTP请求 浏览器生成一个HTTP GET请求: GET /index.html HTTP/1.1 Host: www.example.com User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) Accept: text/html,application/xhtml+xml Accept-Language: zh-CN,zh;q=0.9,en;q=0.8 Accept-Encoding: gzip, deflate Connection: keep-alive 关键信息: 请求方法:GET 请求路径:/index.html 协议版本:HTTP/1.1 Host头:www.example.com(虚拟主机标识) User-Agent:浏览器标识 Connection:keep-alive(保持连接) 此时的数据:只有HTTP请求本身,还没有任何网络信息。 ...

2025-11-20 · maneng

TCP/IP四层模型:理论与实践的平衡

引言 上一篇我们学习了OSI七层模型,理解了网络分层的设计哲学。但实际工作中,我们更常听到的是: “这是个TCP/IP的问题” “HTTP运行在TCP之上” “IP地址是网络层的” 很少有人说"这是会话层的问题"或"表示层出错了"。 为什么?因为互联网实际使用的是TCP/IP四层模型,而不是OSI七层模型。 TCP/IP模型的诞生 历史背景 1969年:ARPANET诞生(互联网的前身) 1974年:TCP/IP协议诞生 1981年:TCP/IP正式分离为TCP和IP 1983年:ARPANET全面采用TCP/IP 1984年:OSI模型发布 时间线:TCP/IP先于OSI模型存在! 为什么TCP/IP胜出? 实践先行 TCP/IP先在ARPANET上实现 经过实际验证,稳定可靠 已经有大量应用基于TCP/IP 简洁实用 4层比7层简单 避免过度设计 工程实践优于理论完美 开放免费 TCP/IP协议是开放的 任何人都可以实现 OSI标准复杂且需要付费 TCP/IP四层模型 ┌─────────────────────────────────┐ │ 应用层 (Application Layer) │ HTTP, FTP, DNS, SMTP ├─────────────────────────────────┤ │ 传输层 (Transport Layer) │ TCP, UDP ├─────────────────────────────────┤ │ 网络层 (Internet Layer) │ IP, ICMP, ARP ├─────────────────────────────────┤ │ 链路层 (Link Layer) │ Ethernet, WiFi └─────────────────────────────────┘ 与OSI模型的对应关系 OSI七层 TCP/IP四层 ──────────────────────────── 应用层 ] 表示层 ] ───→ 应用层 会话层 ] ──────────────────────────── 传输层 ───→ 传输层 ──────────────────────────── 网络层 ───→ 网络层 ──────────────────────────── 数据链路层] 物理层 ] ───→ 链路层 ──────────────────────────── 每层详解 1. 链路层(Link Layer) 职责:在直连设备之间传输数据帧 ...

2025-11-20 · maneng

OSI七层模型详解:网络分层的设计哲学

引言 上一篇我们理解了为什么需要计算机网络。现在面临一个问题:如何设计一个网络系统,让全世界的计算机都能互相通信? 这是一个极其复杂的问题,需要解决: 🔌 如何连接?(物理层面) 📮 如何寻址?(找到目标计算机) 📦 如何传输?(可靠性、顺序) 💬 如何通信?(应用协议) 如果把所有功能混在一起,系统将变得无比复杂和脆弱。 解决方案:分层(Layering) - 这是软件工程中最重要的设计思想之一。 第一性原理:为什么要分层? 类比:寄快递的分层 假设你要从北京寄一本书到上海的朋友: 不分层的方式(自己全干) 你需要: 找个箱子,包装书 写收件人地址 开车送到物流中心 规划运输路线(走哪条高速?) 跟踪包裹位置 送到朋友家门口 问题: ❌ 太复杂了!你需要掌握所有技能 ❌ 效率低!每个人都要重复这些工作 ❌ 不专业!你规划的路线可能不是最优的 分层的方式(专业分工) 第1层:包装层(你) 职责:包装书,写地址 输出:打包好的快递 第2层:收件层(快递员) 职责:上门取件,送到网点 输出:快递到达网点 第3层:运输层(物流公司) 职责:规划路线,跨城运输 输出:快递到达目标城市 第4层:派送层(派送员) 职责:最后一公里配送 输出:快递送到收件人手中 优势: ✅ 简单:每层只关注自己的职责 ✅ 高效:专业的人做专业的事 ✅ 灵活:可以替换某一层(换物流公司) 分层的核心价值 降低复杂度 将大问题分解为小问题 每层只需关注自己的职责 上层不需要知道下层的实现细节 提高灵活性 可以独立修改某一层 只要接口不变,不影响其他层 容易替换和升级 促进标准化 每层有明确的标准和协议 不同厂商可以互操作 避免供应商锁定 OSI七层模型 OSI(Open Systems Interconnection)模型是**国际标准化组织(ISO)**在1984年提出的网络分层模型。 ...

2025-11-20 · maneng

如约数科科技工作室

浙ICP备2025203501号

👀 本站总访问量 ...| 👤 访客数 ...| 📅 今日访问 ...