作者:engleliu,腾讯 PCG 开发工程师
本文主要介绍 TCP 拥塞控制算法,内容多来自网上各个大佬的博客及《TCP/IP 详解》一书,在此基础上进行梳理总结,与大家分享 。因水平有限,内容多有不足之处,敬请谅解 。一、TCP 首部格式在了解 TCP 的拥塞控制之前,先来看看 TCP 的首部格式和一些基本概念 。
TCP 头部标准长度是 20 字节 。包含源端口、目的端口、序列号、确认号、数据偏移、保留位、控制位、窗口大小、校验和、紧急指针、选项等 。
文章插图
TCP 首部格式
1.1 数据偏移(Data Offset)该字段长 4 位,单位为 4 字节 。表示为 TCP 首部的长度 。所以 TCP 首部长度最多为 60 字节 。
1.2 控制位目前的 TCP 控制位如下,其中 CWR 和 ECE 用于拥塞控制,ACK、RST、SYN、FIN 用于连接管理及数据传输 。
CWR:用于 IP 首部的 ECN 字段 。ECE 为 1 时,则通知对方已将拥塞窗口缩小 。ECE:在收到数据包的 IP 首部中 ECN 为 1 时将 TCP 首部中的 ECE 设置为 1,表示从对方到这边的网络有拥塞 。URG:紧急模式ACK:确认PSH:推送,接收方应尽快给应用程序传送这个数据 。没用到RST:该位为 1 表示 TCP 连接中出现异常必须强制断开连接 。SYN:初始化一个连接的同步序列号FIN:该位为 1 表示今后不会有数据发送,希望断开连接 。
1.3 窗口大小(Window)该字段长度位 16 位,即 TCP 数据包长度位 64KB 。可以通过 Options 字段的 WSOPT 选项扩展到 1GB 。1.4 选项(Options)受 Data Offset 控制,长度最大为 40 字节 。一般 Option 的格式为 TLV 结构:
文章插图
常见的 TCP Options 有,SACK 字段就位于该选项中 。:
文章插图
TCP Options
1.5 SACK 选项SACK 包括了两个 TCP 选项,一个选项用于标识是否支持 SACK,是在 TCP 连接建立时发送;另一种选项则包含了具体的 SACK 信息 。
- SACK_Permitted 选项,该选项只允许在 TCP 连接建立时,有 SYN 标志的包中设置,也即 TCP 握手的前两个包中,分别表示通信的两方各自是否支持 SACK 。
TCP SACK-Permitted Option:Kind: 4Length: Variable+----------+----------+| Kind=4| Length=2 |+----------+----------+
- SACK(选择性确认) 选项位于 Options 中 。该选项参数告诉对方已经接收到并缓存的不连续的数据块,发送方可根据此信息检查究竟是哪些块丢失,从而发送相应的数据块 。受 TCP 包长度限制,TCP 包头最多包含四组 SACK 字段 。
TCP SACK Option:Kind: 5Length: Variable+--------+--------+| Kind=5 | Length |+--------+--------+--------+--------+|Left Edge Of lst Block|+--------+--------+--------+--------+|Right Edge Of lst Block|+--------+--------+--------+--------+|...|+--------+--------+--------+--------+|Left Edge Of nth Block|+--------+--------+--------+--------+|Right Edge Of nth Block|+--------+--------+--------+--------+
- SACK 的工作原理如下图所示,接收方收到 500-699 的数据包,但没有收到 300-499 的数据包就会回 SACK(500-700) 给发送端,表示收到 500-699 的数据 。
文章插图
SACK 的工作原理
二、滑动窗口和包守恒原则2.1 滑动窗口为了解决可靠传输以及包乱序的问题,TCP 引入滑动窗口的概念 。在传输过程中,client 和 server 协商接收窗口 rwnd,再结合拥塞控制窗口 cwnd 计算滑动窗口 swnd 。在 linux 内核实现中,滑动窗口 cwnd 是以包为单位,所以在计算 swnd 时需要乘上 mss(最大分段大小) 。
文章插图
如下图所示滑动窗口包含 4 部分:
- 已收到 ack 确认的数据;
- 已发还没收到 ack 的;
- 在窗口中还没有发出的(接收方还有空间);
- 窗口以外的数据(接收方没空间) 。
文章插图
TCP滑动窗口
滑动后的示意图如下(收到 36 的 ack,并发出了 46-51 的数据):
文章插图
TCP滑动后示意图
2.2 包守恒原则
文章插图
推荐阅读
- 如何基于TCP/IP协议进行MFC Socket网络通讯编程
- Treck TCP/IP协议库多个漏洞安全风险通告
- tcp,icmp,http 基于wireshark报文分析快速过滤报文时延
- 服务器海量TCP连接如何高效保活?
- 两万字深度介绍分布式,一文入魂
- TCP 半连接队列和全连接队列满了,怎么破?
- 说起来 TCP 的连接与释放真是个浪漫的故事呢!
- 网络安全常见协议解析:TCP、UDP、HTTP、FTP、SMTP等之间的区别
- 全网最强TCP/IP拥塞控制总结
- 轻松学习http知识让枯燥的内容变得生动有趣:TCP/IP四层模型