传输层
传输层提供的服务
传输层的功能
传输层是OSI参考模型中的第四层,位于网络层和会话层之间,为应用层提供服务。传输层的主要功能是在不同主机的应用程序之间提供端到端的通信服务。
主要功能
-
进程到进程的通信
- 传输层提供进程级别的通信,而不仅仅是主机到主机的通信
- 通过端口号区分同一主机上的不同应用程序
- 实现了网络层的复用和分用功能
-
传输控制
- 连接管理:建立、维护和释放连接
- 可靠传输:确保数据的完整性和顺序性
- 流量控制:防止发送方淹没接收方
- 拥塞控制:防止网络过载
-
差错检测和恢复
- 检测传输过程中的数据错误
- 对损坏或丢失的数据进行重传
- 确保数据的完整性
-
数据分段和重组
- 将应用层的大数据块分割成适合网络传输的小段
- 在接收端将分段重新组装成原始数据
-
服务质量保证
- 提供不同级别的服务质量
- 支持实时应用的需求
- 确保带宽和延迟要求
传输层协议
传输层主要有两种协议:
-
TCP(传输控制协议)
- 面向连接的可靠传输协议
- 提供流量控制和拥塞控制
- 保证数据的顺序和完整性
- 适用于要求高可靠性的应用
-
UDP(用户数据报协议)
- 无连接的不可靠传输协议
- 不提供流量控制和拥塞控制
- 传输效率高,开销小
- 适用于实时应用和简单请求-响应场景
传输层与网络层的关系
传输层建立在网络层服务之上,但又与网络层有明显的区别:
- 网络层:提供主机到主机的通信,关注数据包如何从源主机路由到目的主机
- 传输层:提供进程到进程的通信,关注应用程序之间的数据传输
传输层利用网络层提供的服务,同时弥补了网络层服务的不足,为应用程序提供更加完善的通信服务。
传输层寻址与端口
传输层寻址是指在网络通信中如何唯一标识一个应用程序的过程。由于一台主机上可能同时运行多个网络应用程序,因此需要一种机制来区分这些应用程序,这就是端口的作用。
端口的概念
端口是传输层的一个重要概念,它是应用程序与传输层协议之间的接口。每个端口用一个16位的整数表示,因此端口号的取值范围是0~65535。
端口的分类
-
熟知端口(Well-known Ports):0~1023
- 这些端口由IANA(Internet Assigned Numbers Authority)统一管理
- 分配给最常用的应用程序
- 例如:HTTP(80)、FTP(21)、SMTP(25)、DNS(53)等
-
注册端口(Registered Ports):1024~49151
- 这些端口也由IANA管理,但不如熟知端口那样严格
- 分配给特定的应用程序或服务
- 例如:MySQL(3306)、RDP(3389)等
-
动态/私有端口(Dynamic/Private Ports):49152~65535
- 这些端口不分配给特定应用程序
- 客户端程序通常使用这些端口作为源端口
- 也称为临时端口(Ephemeral Ports)
常用端口号
| 服务 | 端口号 | 传输层协议 | 描述 |
|---|---|---|---|
| FTP | 20, 21 | TCP | 文件传输协议 |
| SSH | 22 | TCP | 安全外壳协议 |
| Telnet | 23 | TCP | 远程登录协议 |
| SMTP | 25 | TCP | 简单邮件传输协议 |
| DNS | 53 | TCP/UDP | 域名系统 |
| HTTP | 80 | TCP | 超文本传输协议 |
| POP3 | 110 | TCP | 邮局协议版本3 |
| NTP | 123 | UDP | 网络时间协议 |
| IMAP | 143 | TCP | 互联网消息访问协议 |
| HTTPS | 443 | TCP | 安全超文本传输协议 |
| SNMP | 161 | UDP | 简单网络管理协议 |
套接字(Socket)
套接字是网络编程中的一个重要概念,它是网络通信的端点。一个套接字由IP地址和端口号组成,格式为:IP地址:端口号。
例如:192.168.1.100:8080 表示IP地址为192.168.1.100的主机上端口号为8080的套接字。
端口的工作原理
-
服务器端
- 服务器应用程序在特定端口上监听
- 等待客户端的连接请求
- 接收到请求后建立连接
-
客户端
- 客户端应用程序使用随机选择的临时端口
- 向服务器的熟知端口发送请求
- 建立连接后进行数据交换
多路复用与多路分用
传输层的端口机制实现了多路复用和多路分用:
- 多路复用(Multiplexing):发送方将多个应用程序的数据合并到一个传输层实体中发送
- 多路分用(Demultiplexing):接收方根据端口号将收到的数据分发给相应的应用程序
示例
当你同时浏览网页、收发邮件和使用即时通讯软件时,传输层通过不同的端口号将这些应用程序的数据分开,确保数据能够正确地发送到对应的应用程序。
端口与安全
端口也是网络安全的一个重要方面:
- 端口扫描:攻击者通过扫描目标主机的端口来发现开放的服务
- 端口过滤:防火墙可以根据端口号过滤网络流量
- 端口转发:可以将外部端口的请求转发到内部主机的特定端口
动态端口分配
当客户端发起连接时,操作系统会从动态端口范围中分配一个未使用的端口作为源端口。这种分配方式有以下特点:
- 端口号是随机选择的
- 端口在使用完毕后会被释放,可供后续连接使用
- 不同操作系统的动态端口范围可能不同
端口与NAT
在网络地址转换(NAT)中,端口也扮演着重要角色:
- PAT(端口地址转换):通过修改端口号来实现多个内部主机共享一个公网IP地址
- 端口映射:将外部端口的请求转发到内部主机的特定端口
- 端口触发:根据内部主机的连接动态开放外部端口
无连接服务与面向连接服务
传输层提供两种基本的服务类型:无连接服务和面向连接服务。这两种服务在可靠性、开销和适用场景等方面有显著差异。
无连接服务
无连接服务是一种不建立连接就直接传输数据的服务模式,每个数据包都是独立传输的。
特点
-
无需建立连接
- 发送方不需要事先与接收方建立连接
- 每个数据包都独立处理,不依赖于其他数据包
-
不可靠传输
- 不保证数据包的到达
- 不保证数据包的顺序
- 不保证数据包的完整性
-
简单高效
- 协议开销小
- 传输延迟低
- 实现简单
-
无状态
- 服务器不维护客户端的状态信息
- 每个请求都是独立的
应用场景
- 实时应用:如视频会议、语音通话、在线游戏等
- 请求-响应应用:如DNS查询、SNMP等
- 广播和多播应用
- 对可靠性要求不高的应用
代表协议
- UDP(用户数据报协议)是典型的无连接传输协议
面向连接服务
面向连接服务是一种在传输数据前需要先建立连接的服务模式,数据传输在已建立的连接上进行。
特点
-
需要建立连接
- 传输数据前需要先建立连接
- 连接建立后才能进行数据传输
- 传输结束后需要释放连接
-
可靠传输
- 保证数据包的到达
- 保证数据包的顺序
- 保证数据包的完整性
-
复杂但可靠
- 协议开销大
- 传输延迟相对较高
- 实现复杂
-
有状态
- 服务器需要维护客户端的状态信息
- 记录连接的当前状态
连接的三个阶段
-
连接建立
- 客户端向服务器发送连接请求
- 服务器确认请求并响应
- 客户端再次确认,建立连接
-
数据传输
- 在已建立的连接上传输数据
- 提供流量控制和拥塞控制
- 确保数据的可靠传输
-
连接释放
- 任何一方都可以请求释放连接
- 双方协商后释放连接
- 释放相关资源
应用场景
- 文件传输:如FTP
- 网页浏览:如HTTP
- 电子邮件:如SMTP、POP3、IMAP
- 远程登录:如Telnet、SSH
代表协议
- TCP(传输控制协议)是典型的面向连接传输协议
两种服务的比较
| 特性 | 无连接服务 | 面向连接服务 |
|---|---|---|
| 连接建立 | 不需要 | 需要 |
| 可靠性 | 不可靠 | 可靠 |
| 顺序保证 | 不保证 | 保证 |
| 流量控制 | 无 | 有 |
| 拥塞控制 | 无 | 有 |
| 开销 | 小 | 大 |
| 延迟 | 低 | 高 |
| 状态信息 | 无 | 有 |
| 适用场景 | 实时应用、简单查询 | 文件传输、网页浏览 |
选择考虑因素
在选择使用哪种服务时,需要考虑以下因素:
-
可靠性要求
- 高可靠性要求:选择面向连接服务
- 低可靠性要求:选择无连接服务
-
实时性要求
- 高实时性要求:选择无连接服务
- 低实时性要求:选择面向连接服务
-
网络状况
- 网络状况好:两种服务都可以考虑
- 网络状况差:优先选择面向连接服务
-
应用特性
- 流媒体应用:优先选择无连接服务
- 文件传输应用:优先选择面向连接服务
混合使用
在实际应用中,有些应用会同时使用两种服务。例如,DNS查询使用UDP(无连接),而区域传输使用TCP(面向连接)。这种混合使用可以根据不同的需求选择最适合的服务类型。
UDP 协议
UDP数据报
UDP(User Datagram Protocol,用户数据报协议)是一种简单的无连接传输层协议。UDP数据报是UDP协议传输数据的基本单位。
UDP数据报结构
UDP数据报由UDP首部和UDP数据两部分组成,其结构相对简单:
0 7 8 15 16 23 24 31
+--------+--------+--------+--------+
| 源端口号 | 目的端口号 |
+--------+--------+--------+--------+
| 长度 | 检验和 |
+--------+--------+--------+--------+
| 数据部分(如果有) |
| |
+----------------------------------+
UDP首部字段
-
源端口号(16位)
- 标识发送方应用程序的端口号
- 如果不需要对方回复,可以设置为0
- 取值范围:0~65535
-
目的端口号(16位)
- 标识接收方应用程序的端口号
- 用于将数据报交付给正确的应用程序
- 取值范围:0~65535
-
长度(16位)
- UDP数据报的总长度,包括首部和数据部分
- 最小值为8字节(仅首部)
- 最大值为65535字节
-
检验和(16位)
- 用于检测UDP数据报在传输过程中是否出错
- 计算范围包括UDP首部、UDP数据和一个伪首部
- 可选字段,IPv4中可以设置为0表示不使用,IPv6中必须使用
UDP伪首部
UDP检验和的计算包含一个伪首部,伪首部不是UDP数据报的真正部分,只用于计算检验和:
0 7 8 15 16 23 24 31
+--------+--------+--------+--------+
| 源IP地址 |
+--------+--------+--------+--------+
| 目的IP地址 |
+--------+--------+--------+--------+
| 0 | 协议(17)| UDP长度 |
+--------+--------+--------+--------+
伪首部包含以下字段: - 源IP地址(32位) - 目的IP地址(32位) - 0(8位) - 协议字段(8位,UDP为17) - UDP长度(16位)
UDP数据报的特点
-
固定长度的首部
- UDP首部固定为8字节,简单高效
- 相比TCP的20字节首部,开销更小
-
无连接
- 发送数据前不需要建立连接
- 每个数据报独立传输
-
不可靠传输
- 不保证数据报的到达
- 不保证数据报的顺序
- 不保证数据报的完整性
-
尽力交付
- UDP尽力交付数据报,但不保证成功
- 网络拥塞时可能会丢弃数据报
UDP数据报的封装
UDP数据报在网络中的封装过程如下:
+------------------+
| 应用数据 |
+------------------+
| UDP首部 | <-- UDP数据报
+------------------+
| IP首部 | <-- IP数据报
+------------------+
| 帧首部 | <-- 帧
+------------------+
| 帧尾 |
+------------------+
UDP数据报的长度限制
UDP数据报的最大长度受以下因素限制:
-
理论限制
- UDP长度字段16位,最大值为65535字节
- UDP首部8字节,数据部分最大65507字节
-
实际限制
- IP数据报的最大长度为65535字节
- IP首部20字节(无选项),UDP首部8字节
- 实际UDP数据部分最大65507字节
-
应用层限制
- 许多应用程序限制UDP数据报长度
- 例如DNS限制为512字节(传统)或4096字节(EDNS0)
UDP数据报的优缺点
优点
-
简单高效
- 协议简单,实现容易
- 首部开销小,传输效率高
-
低延迟
- 无需建立连接,减少传输延迟
- 适合实时应用
-
支持广播和多播
- 支持一对多通信
- 适合多媒体应用
缺点
-
不可靠
- 不保证数据报的到达
- 不保证数据报的顺序
- 不保证数据报的完整性
-
无流量控制
- 可能导致接收方缓冲区溢出
- 可能导致网络拥塞
-
无拥塞控制
- 可能加剧网络拥塞
- 不适合高负载网络
UDP的应用场景
-
实时应用
- 视频会议
- 语音通话(VoIP)
- 在线游戏
- 流媒体
-
请求-响应应用
- DNS查询
- SNMP
- TFTP(简单文件传输协议)
-
广播和多播应用
- 视频广播
- 股票行情
- 在线教育
-
简单数据传输
- 日志收集
- 监控数据
- 传感器数据
UDP与TCP的比较
UDP和TCP是传输层两种主要协议,它们各有优缺点:
- UDP简单高效,适合实时应用,但不可靠
- TCP复杂但可靠,适合文件传输等要求可靠性的应用
- 选择哪种协议取决于应用的具体需求
UDP校验
UDP校验和是UDP协议中用于检测数据传输错误的机制,虽然它是可选的(在IPv4中),但在实际应用中通常都会使用。
UDP校验和的作用
UDP校验和主要用于:
-
检测数据传输错误
- 检测UDP首部和数据在传输过程中是否发生改变
- 防止损坏的数据被应用程序接收
-
提供基本的可靠性
- 虽然UDP是不可靠协议,但校验和提供了基本的错误检测
- 接收方可以选择丢弃校验和错误的数据报
-
保护端到端数据完整性
- 校验和覆盖从源主机到目的主机的整个传输路径
- 包括中间路由器可能对数据报的修改
UDP校验和的计算
UDP校验和的计算包括三个部分:
- UDP伪首部
- UDP首部
- UDP数据部分
UDP伪首部结构
0 7 8 15 16 23 24 31
+--------+--------+--------+--------+
| 源IP地址 |
+--------+--------+--------+--------+
| 目的IP地址 |
+--------+--------+--------+--------+
| 0 | 协议(17)| UDP长度 |
+--------+--------+--------+--------+
伪首部包含以下字段: - 源IP地址(32位):发送方的IP地址 - 目的IP地址(32位):接收方的IP地址 - 0(8位):填充字段,设置为0 - 协议字段(8位):设置为17(UDP的协议号) - UDP长度(16位):UDP数据报的总长度
校验和计算过程
UDP校验和的计算步骤如下:
-
准备数据
- 将UDP伪首部、UDP首部和UDP数据部分拼接在一起
- 如果数据部分长度为奇数,添加一个全零的字节进行填充
-
按16位分组
- 将整个数据按16位(2字节)进行分组
- 每个组被视为一个16位的二进制数
-
求和
- 将所有16位数相加
- 如果有进位,将进位加到结果的低位(回卷)
-
取反
- 将求和结果按位取反
- 得到的结果就是UDP校验和
校验和验证
接收方验证UDP校验和的步骤:
-
准备数据
- 接收方构造相同的伪首部(使用接收到的IP地址)
- 将伪首部、UDP首部和UDP数据部分拼接
-
计算校验和
- 按照发送方相同的算法计算校验和
- 如果数据部分长度为奇数,添加一个全零的字节
-
验证结果
- 如果计算结果为0,说明数据传输正确
- 如果计算结果不为0,说明数据传输有错误
校验和计算示例
假设有以下UDP数据报:
- 源IP地址:192.168.1.1
- 目的IP地址:192.168.1.2
- 源端口号:1234(0x04D2)
- 目的端口号:80(0x0050)
- 长度:12字节(0x000C)
- 数据:"Hello"(5字节)
计算过程:
-
构造伪首部
源IP地址:C0 A8 01 01 目的IP地址:C0 A8 01 02 协议/长度:00 11 00 0C -
UDP首部
源端口:04 D2 目的端口:00 50 长度:00 0C 校验和:00 00(初始为0) -
数据部分
"Hello":48 65 6C 6C 6F 填充:00(因为数据长度为奇数) -
按16位分组并求和
C0A8 + 0101 + C0A8 + 0102 + 0011 + 000C + 04D2 + 0050 + 000C + 0000 + 4865 + 6C6C + 6F00 -
计算结果并取反
- 计算所有16位数的和
- 处理进位
- 按位取反得到最终校验和
UDP校验和的特点
-
可选性
- 在IPv4中,UDP校验和是可选的
- 发送方可以将校验和字段设置为0表示不使用
- 在IPv6中,UDP校验和是必须的
-
覆盖范围广
- 校验和覆盖伪首部、UDP首部和数据部分
- 可以检测到IP地址错误
-
简单高效
- 计算简单,开销小
- 适合UDP这种简单协议
-
错误检测能力有限
- 只能检测到奇数位错误
- 不能检测到偶数位错误
- 不能纠正错误,只能检测
校验和错误处理
当接收方检测到校验和错误时,可以采取以下策略:
-
丢弃数据报
- 直接丢弃校验和错误的数据报
- 不通知发送方
- 应用程序不会收到这个数据报
-
记录错误
- 记录校验和错误事件
- 用于网络监控和故障诊断
-
传递给应用程序
- 将错误标记传递给应用程序
- 由应用程序决定如何处理
校验和的性能影响
-
计算开销
- 发送方和接收方都需要计算校验和
- 对于高性能应用,可能成为瓶颈
-
网络开销
- 校验和字段增加2字节的开销
- 相对于UDP首部总开销(8字节),占25%
-
错误检测能力
- 提供基本的错误检测能力
- 对于关键应用,可能需要更强的错误检测机制
UDP校验和与TCP校验和的比较
| 特性 | UDP校验和 | TCP校验和 |
|---|---|---|
| 可选性 | IPv4可选,IPv6必须 | 必须使用 |
| 覆盖范围 | 伪首部、首部、数据 | 伪首部、首部、数据 |
| 计算复杂度 | 简单 | 简单 |
| 错误检测能力 | 基本错误检测 | 基本错误检测 |
| 性能影响 | 小 | 小 |
实际应用中的考虑
-
是否使用校验和
- 大多数实现默认使用校验和
- 在可靠网络中,可能选择不使用以提高性能
-
校验和的局限性
- 不能替代应用层的错误检测
- 对于关键数据,应用层应实现自己的校验机制
-
性能优化
- 硬件加速校验和计算
- 批量处理减少计算开销
UDP校验和的重要性
虽然UDP校验和是可选的,但实际应用中几乎总是使用它:
- 提供基本的错误检测能力
- 防止损坏数据被应用程序处理
- 开销小,收益大
- 在IPv6中是必须的,因此实现上通常统一使用
TCP协议
TCP段
TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层协议。TCP段是TCP协议传输数据的基本单位,包含TCP首部和数据部分。
TCP段结构
TCP段由TCP首部和TCP数据两部分组成,其结构相对复杂:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 源端口号 | 目的端口号 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 序列号 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 确认号 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 数据 | |U|A|P|R|S|F| |
| 偏移 | 保留 |R|C|S|S|Y|I| 窗口 |
| | |G|K|H|T|N|N| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 检验和 | 紧急指针 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 选项 | 填充 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 数据部分 |
| ... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
TCP首部字段详解
-
源端口号(16位)
- 标识发送方应用程序的端口号
- 取值范围:0~65535
-
目的端口号(16位)
- 标识接收方应用程序的端口号
- 用于将TCP段交付给正确的应用程序
- 取值范围:0~65535
-
序列号(32位)
- 标识当前TCP段中第一个数据字节在整个字节流中的位置
- 用于保证数据的顺序性和可靠性
- 如果是SYN段,序列号是初始序列号(ISN)
-
确认号(32位)
- 表示期望接收的下一个字节的序列号
- 用于确认已接收的数据
- 只有ACK标志位为1时才有效
-
数据偏移(4位)
- 表示TCP首部的长度,以4字节为单位
- 最小值为5(20字节首部)
- 最大值为15(60字节首部,包含40字节选项)
-
保留(6位)
- 为将来使用而保留
- 必须设置为0
-
标志位(6位)
- URG:紧急指针有效
- ACK:确认号有效
- PSH:推送功能
- RST:重置连接
- SYN:同步序列号,用于建立连接
- FIN:结束连接,表示发送方没有更多数据要发送
-
窗口大小(16位)
- 用于流量控制,表示接收方可接收的字节数
- 从确认号开始计算
- 取值范围:0~65535
-
检验和(16位)
- 用于检测TCP段在传输过程中是否出错
- 计算范围包括TCP伪首部、TCP首部和TCP数据
- 必须使用,不可选
-
紧急指针(16位) - 只有URG标志位为1时才有效 - 指向紧急数据在数据段中的位置 - 表示从序列号开始的偏移量
-
选项(可变长度) - 提供额外的功能 - 常见选项包括: - 最大段大小(MSS) - 窗口扩大因子 - 时间戳 - 选择确认(SACK)许可
-
填充(可变长度) - 确保TCP首部是4字节的整数倍 - 填充0
TCP伪首部
TCP检验和的计算包含一个伪首部,伪首部不是TCP段的真正部分,只用于计算检验和:
0 7 8 15 16 23 24 31
+--------+--------+--------+--------+
| 源IP地址 |
+--------+--------+--------+--------+
| 目的IP地址 |
+--------+--------+--------+--------+
| 0 | 协议(6) | TCP长度 |
+--------+--------+--------+--------+
伪首部包含以下字段:
- 源IP地址(32位)
- 目的IP地址(32位)
- 0(8位)
- 协议字段(8位,TCP为6)
- TCP长度(16位)
TCP段的特点
-
面向连接
- 传输数据前需要建立连接
- 数据传输结束后需要释放连接
-
可靠传输
- 通过序列号和确认号保证数据的可靠性
- 通过重传机制处理丢失的数据段
-
字节流服务
- TCP提供的是字节流服务,不是报文服务
- 应用程序交付给TCP的数据被看作是无结构的字节流
-
全双工通信
- 支持同时进行双向数据传输
- 每个方向都有独立的序列号和确认号
-
流量控制
- 通过滑动窗口机制进行流量控制
- 防止发送方淹没接收方
-
拥塞控制
- 通过拥塞窗口进行拥塞控制
- 防止网络拥塞导致性能下降
TCP段的封装
TCP段在网络中的封装过程如下:
+------------------+
| 应用数据 |
+------------------+
| TCP首部 | <-- TCP段
+------------------+
| IP首部 | <-- IP数据报
+------------------+
| 帧首部 | <-- 帧
+------------------+
| 帧尾 |
+------------------+
TCP段的长度限制
TCP段的最大长度受以下因素限制:
-
理论限制
- TCP序列号32位,理论上可传输约4GB数据
- TCP窗口大小16位,最大65535字节(可扩展)
-
实际限制
- IP数据报的最大长度为65535字节
- IP首部20字节(无选项),TCP首部20字节(无选项)
- 实际TCP数据部分最大65515字节
-
路径MTU限制
- 受网络路径中MTU最小的链路限制
- 通常以太网MTU为1500字节
- 实际TCP数据部分通常为1460字节(MSS)
TCP段的分类
根据TCP段的功能和标志位,可以将TCP段分为以下几类:
-
连接建立段
- SYN段:用于建立连接
- SYN+ACK段:用于确认连接请求
-
数据传输段
- 普通数据段:传输应用数据
- ACK段:确认接收到的数据
- PSH段:推送数据到接收方应用层
-
连接释放段
- FIN段:用于关闭连接
- FIN+ACK段:确认关闭请求
-
异常处理段
- RST段:用于重置连接
- URG段:用于传输紧急数据
TCP段的处理流程
-
发送方处理
- 应用数据分段
- 添加TCP首部
- 计算检验和
- 发送TCP段
-
接收方处理
- 验证检验和
- 检查序列号
- 处理标志位
- 提取数据并交付给应用层
-
重传处理
- 超时重传
- 快速重传
- 选择确认(SACK)
TCP段的优化
-
延迟确认
- 接收方延迟发送ACK段
- 希望有数据可以捎带确认
-
Nagle算法
- 减少小数据段的发送
- 提高网络利用率
-
窗口扩大
- 扩大窗口大小,提高吞吐量
- 适用于高延迟、高带宽网络
-
时间戳
- 用于测量往返时间(RTT)
- 防止序列号回绕导致的问题
TCP段与UDP数据报的比较
TCP段和UDP数据报都是传输层的数据单元,但有以下主要区别:
- TCP段包含更多的控制信息,提供可靠传输
- UDP数据报结构简单,提供尽力交付
- TCP是面向字节流的,UDP是面向报文的
- TCP有连接管理,UDP无连接
TCP连接管理
TCP连接管理是TCP协议的核心功能之一,负责建立、维护和释放TCP连接。TCP连接管理通过三次握手建立连接,通过四次挥手释放连接,确保数据传输的可靠性。
TCP连接的基本概念
-
连接标识
- 通过套接字地址(IP地址+端口号)唯一标识连接
- 四元组:{源IP, 源端口, 目的IP, 目的端口}
- 同一主机上的不同连接通过不同端口区分
-
连接状态
- TCP连接有多种状态,通过状态机管理
- 状态转换由事件触发(如接收段、超时等)
- 每个连接在两端都有独立的状态
-
连接资源
- 每个连接占用系统资源(内存、控制块等)
- 连接数量受系统限制
- 需要合理管理连接资源
TCP连接建立(三次握手)
TCP连接建立采用三次握手过程,确保双方都准备好进行数据传输:
客户端 服务器
| |
| 1. SYN (seq=x) -------> |
| | CLOSED -> LISTEN
| | LISTEN -> SYN_RCVD
| <------ 2. SYN+ACK (seq=y, ack=x+1) |
| SYN_SENT -> ESTABLISHED |
| 3. ACK (ack=y+1) ------> |
| | SYN_RCVD -> ESTABLISHED
| |
| 数据传输开始 |
-
第一次握手(SYN)
- 客户端发送SYN段,请求建立连接
- 选择初始序列号seq=x
- 客户端状态从CLOSED变为SYN_SENT
-
第二次握手(SYN+ACK)
- 服务器收到SYN后,回复SYN+ACK段
- 选择初始序列号seq=y
- 确认号ack=x+1,表示已收到客户端SYN
- 服务器状态从LISTEN变为SYN_RCVD
-
第三次握手(ACK)
- 客户端收到SYN+ACK后,发送ACK段
- 确认号ack=y+1,表示已收到服务器SYN
- 客户端状态从SYN_SENT变为ESTABLISHED
- 服务器收到ACK后,状态从SYN_RCVD变为ESTABLISHED
三次握手的作用
-
同步初始序列号
- 双方交换初始序列号,确保数据传输的可靠性
- 防止已失效的连接请求被误认为是新连接
-
确认双方准备就绪
- 确保客户端和服务器都愿意建立连接
- 验证双方都有足够的资源处理连接
-
协商连接参数
- 可以在SYN段中携带选项(如MSS、窗口缩放等)
- 双方协商连接参数,优化传输性能
TCP连接释放(四次挥手)
TCP连接释放采用四次挥手过程,确保双方都完成数据传输:
客户端 服务器
| |
| 1. FIN (seq=u) -------> |
| | ESTABLISHED -> CLOSE_WAIT
| ESTABLISHED -> FIN_WAIT_1 |
| <------ 2. ACK (ack=u+1) |
| FIN_WAIT_1 -> FIN_WAIT_2 |
| | CLOSE_WAIT -> LAST_ACK
| <------ 3. FIN (seq=v) |
| | 发送剩余数据
| 4. ACK (ack=v+1) ------> |
| FIN_WAIT_2 -> TIME_WAIT |
| | LAST_ACK -> CLOSED
| 等待2MSL后 |
| TIME_WAIT -> CLOSED |
| |
-
第一次挥手(FIN)
- 主动关闭方发送FIN段,请求释放连接
- 表示已发送完所有数据
- 状态从ESTABLISHED变为FIN_WAIT_1
-
第二次挥手(ACK)
- 被动关闭方收到FIN后,回复ACK段
- 确认号ack=u+1,表示已收到FIN
- 主动关闭方状态从FIN_WAIT_1变为FIN_WAIT_2
- 被动关闭方状态从ESTABLISHED变为CLOSE_WAIT
-
第三次挥手(FIN)
- 被动关闭方发送完剩余数据后,发送FIN段
- 表示也已发送完所有数据
- 状态从CLOSE_WAIT变为LAST_ACK
-
第四次挥手(ACK)
- 主动关闭方收到FIN后,回复ACK段
- 确认号ack=v+1,表示已收到FIN
- 状态从FIN_WAIT_2变为TIME_WAIT
- 被动关闭方收到ACK后,状态从LAST_ACK变为CLOSED
- 主动关闭方等待2MSL后,状态从TIME_WAIT变为CLOSED
TIME_WAIT状态
TIME_WAIT状态是TCP连接释放过程中的重要状态:
-
作用
- 确保最后一个ACK能够到达对方
- 等待足够时间使网络中的重复段消失
- 防止"已失效的连接请求"被误认为是新连接
-
持续时间
- 通常为2MSL(Maximum Segment Lifetime)
- MSL是段在网络中的最大生存时间
- 典型值为1-4分钟,实际实现通常为30秒-2分钟
-
问题
- 占用系统资源,限制并发连接数
- 在高并发场景下可能导致资源耗尽
- 需要优化TIME_WAIT处理
TCP连接状态机
TCP连接状态机定义了连接的各种状态及状态转换条件:
+-----------+
| CLOSED |
+-----------+
| 应用被动打开
v
+-----------+
| LISTEN |<------+
+-----------+ |
| 应用主动打开 |
v |
+-----------+ 收到SYN |
| SYN_SENT |------->|
+-----------+ |
| 收到SYN+ACK |
v |
+-----------+ 收到ACK |
|ESTABLISHED|<------+
+-----------+
| 应用关闭
v
+-----------+
| FIN_WAIT_1|
+-----------+
| 收到ACK
v
+-----------+
| FIN_WAIT_2|
+-----------+
| 收到FIN
v
+-----------+
| TIME_WAIT |
+-----------+
| 等待2MSL
v
+-----------+
| CLOSED |
+-----------+
TCP连接管理的问题与优化
-
SYN洪水攻击
- 问题:攻击者发送大量SYN段但不完成握手
- 解决:使用SYN Cookie技术
- 优化:限制半连接队列长度
-
连接资源耗尽
- 问题:系统连接数达到上限
- 解决:增加系统连接数限制
- 优化:使用连接池、长连接复用
-
TIME_WAIT积累
- 问题:大量TIME_WAIT状态占用资源
- 解决:调整TIME_WAIT参数
- 优化:使用SO_REUSEADDR选项
-
连接建立延迟
- 问题:三次握手增加连接建立时间
- 解决:使用TCP Fast Open
- 优化:预建立连接、连接复用
TCP连接选项
TCP连接建立时可以协商各种选项,优化连接性能:
-
MSS(Maximum Segment Size)
- 指定TCP段的最大数据长度
- 通常设置为路径MTU减去IP和TCP首部长度
- 避免IP分片,提高传输效率
-
窗口缩放
- 扩大TCP窗口大小,支持高延迟、高带宽网络
- 使用缩放因子扩大窗口字段
- RFC 1323定义的选项
-
时间戳
- 用于计算RTT,防止序列号回绕
- 提高超时重传的准确性
- RFC 1323定义的选项
-
选择性确认(SACK)
- 允许接收方确认非连续的数据块
- 提高丢包恢复效率
- RFC 2018定义的选项
TCP连接的可靠性保证
TCP连接管理通过多种机制保证连接的可靠性:
-
连接建立可靠性
- 三次握手确保双方都准备好建立连接
- 防止已失效的连接请求被误认为是新连接
- 同步初始序列号,确保数据传输的可靠性
-
连接释放可靠性
- 四次挥手确保双方都完成数据传输
- TIME_WAIT状态确保最后一个ACK能够到达对方
- 等待足够时间使网络中的重复段消失
-
连接状态维护
- 通过状态机管理连接状态
- 超时机制确保连接不会永久停留在某个状态
- 保活机制检测连接是否仍然有效
TCP连接管理是TCP协议的核心功能之一,负责建立、维护和释放TCP连接。TCP连接是全双工的,允许数据在两个方向上同时传输。
TCP连接的特点
-
面向连接
- 传输数据前必须建立连接
- 连接建立后才能进行数据传输
- 数据传输结束后需要释放连接
-
点对点
- TCP连接是两个端点之间的连接
- 不支持广播和多播
-
全双工
- 数据可以同时在两个方向上传输
- 每个方向都有独立的序列号和确认号
-
可靠
- 通过三次握手建立可靠连接
- 通过四次挥手释放连接
TCP连接建立(三次握手)
TCP连接建立过程称为三次握手,确保双方都准备好进行数据传输:
客户端 服务器
| |
| SYN, seq=x |--->
| |
|<--- SYN, ACK, seq=y, ack=x+1
| |
| ACK, ack=y+1 |--->
| |
| 连接建立完成 |
三次握手详细过程
-
第一次握手(SYN)
- 客户端发送SYN段,请求建立连接
- SYN标志位设置为1
- 选择一个初始序列号seq=x
- 客户端进入SYN_SENT状态
-
第二次握手(SYN+ACK)
- 服务器收到SYN段后,回复SYN+ACK段
- SYN和ACK标志位都设置为1
- 选择自己的初始序列号seq=y
- 确认号设置为x+1,表示已收到客户端的SYN
- 服务器进入SYN_RCVD状态
-
第三次握手(ACK)
- 客户端收到SYN+ACK段后,发送ACK段
- ACK标志位设置为1
- 序列号设置为x+1
- 确认号设置为y+1,表示已收到服务器的SYN
- 客户端进入ESTABLISHED状态
- 服务器收到ACK后也进入ESTABLISHED状态
三次握手解决的问题
-
确保双方都准备好
- 客户端确认服务器能够接收数据
- 服务器确认客户端能够接收数据
-
同步初始序列号
- 双方交换初始序列号
- 确保数据传输的顺序性
-
防止旧的连接请求
- 通过序列号防止旧的连接请求被误认为是新连接
TCP连接释放(四次挥手)
TCP连接释放过程称为四次挥手,确保双方都完成了数据传输:
客户端 服务器
| |
| FIN, seq=u |--->
| |
|<--- ACK, ack=u+1
| |
|<--- FIN, seq=v
| |
| ACK, ack=v+1 |--->
| |
| 连接释放完成 |
四次挥手详细过程
-
第一次挥手(FIN)
- 客户端发送FIN段,请求关闭连接
- FIN标志位设置为1
- 序列号seq=u(u是已发送数据的最后一个字节的序号+1)
- 客户端进入FIN_WAIT_1状态
-
第二次挥手(ACK)
- 服务器收到FIN段后,发送ACK段
- ACK标志位设置为1
- 确认号设置为u+1,表示已收到客户端的FIN
- 服务器进入CLOSE_WAIT状态
- 客户端收到ACK后进入FIN_WAIT_2状态
-
第三次挥手(FIN)
- 服务器发送完剩余数据后,发送FIN段
- FIN标志位设置为1
- 序列号seq=v(v是服务器已发送数据的最后一个字节的序号+1)
- 服务器进入LAST_ACK状态
-
第四次挥手(ACK)
- 客户端收到FIN段后,发送ACK段
- ACK标志位设置为1
- 确认号设置为v+1,表示已收到服务器的FIN
- 客户端进入TIME_WAIT状态
- 服务器收到ACK后进入CLOSED状态
TIME_WAIT状态
TIME_WAIT状态是TCP连接释放过程中的一个重要状态:
-
持续时间
- 通常为2倍的最大报文段生存时间(2MSL)
- MSL是报文段在网络中存在的最长时间
-
作用
- 确保最后一个ACK能够到达对方
- 确保本连接的所有报文段都从网络中消失
- 防止旧连接的报文段被新连接误接收
-
问题
- 占用系统资源
- 可能导致端口资源耗尽
TCP连接状态转换
TCP连接状态转换图如下:
+---------+
| CLOSED |
+---------+
|
| 主动打开/被动打开
v
+---------+
| LISTEN |<-------+
+---------+ |
| | 收到SYN
| 发送SYN |
v |
+---------+ |
| SYN_RCVD|--------+
+---------+
|
| 收到ACK
v
+---------+
|ESTABLISHED|
+---------+
|
| 应用程序关闭
v
+---------+
|FIN_WAIT_1|
+---------+
|
| 收到ACK
v
+---------+
|FIN_WAIT_2|
+---------+
|
| 收到FIN
v
+---------+
|TIME_WAIT|
+---------+
|
| 2MSL超时
v
+---------+
| CLOSED |
+---------+
TCP连接重置
TCP连接重置(RST)用于异常情况下终止连接:
-
RST段的特点
- RST标志位设置为1
- 不需要确认
- 接收方立即终止连接
-
使用场景
- 连接请求到达不存在的端口
- 连接出现异常
- 终止半开连接
-
处理方式
- 接收方收到RST后立即释放连接资源
- 不发送ACK确认
TCP连接的优化
-
快速打开(TCP Fast Open)
- 减少连接建立的时间
- 在SYN段中携带应用数据
- 需要服务器和客户端都支持
-
连接复用
- HTTP/1.1的持久连接
- HTTP/2的多路复用
- 减少连接建立和释放的开销
-
连接池
- 应用程序维护一组连接
- 避免频繁创建和销毁连接
- 提高应用程序性能
TCP连接的安全问题
-
SYN洪水攻击
- 攻击者发送大量SYN段
- 不完成三次握手
- 耗尽服务器资源
-
防御措施
- SYN Cookie
- 连接队列限制
- 防火墙过滤
-
连接劫持
- 攻击者猜测序列号
- 插入伪造的TCP段
- 劫持合法连接
-
防御措施
- 随机初始序列号
- 加密传输(如TLS)
- 身份认证
TCP连接管理的重要性
TCP连接管理是TCP协议可靠性的基础:
- 三次握手确保双方都准备好进行数据传输
- 四次挥手确保双方都完成了数据传输
- 状态机制确保连接的正确建立和释放
- 异常处理机制确保连接的可靠性
TCP可靠传输
TCP可靠传输是TCP协议的核心特性之一,确保数据从发送方可靠地传输到接收方。TCP通过多种机制实现可靠传输,包括序列号、确认号、重传机制等。
TCP可靠传输的基本原理
-
序列号
- 为每个字节分配一个序列号
- 确保数据的顺序性
- 用于检测丢失的数据
-
确认机制
- 接收方确认已接收的数据
- 通过确认号告知发送方期望接收的下一个字节
- 支持累积确认
-
重传机制
- 发送方重传未确认的数据
- 包括超时重传和快速重传
- 确保数据的完整性
-
流量控制
- 通过滑动窗口控制发送速率
- 防止接收方缓冲区溢出
- 确保数据的可靠接收
序列号和确认号
-
序列号
- TCP段中第一个数据字节的序列号
- 初始序列号(ISN)是随机选择的
- 序列号空间是32位,循环使用
-
确认号
- 接收方期望接收的下一个字节的序列号
- 确认号是累积的,确认号之前的所有字节都已接收
- ACK标志位为1时确认号才有效
-
序列号和确认号的作用
- 保证数据的顺序性
- 检测丢失的数据
- 去除重复的数据
滑动窗口协议
TCP使用滑动窗口协议实现可靠传输:
-
发送窗口
- 发送方可以发送但未确认的数据范围
- 窗口大小由接收方通告
- 窗口可以滑动,随着数据的发送和确认而移动
-
接收窗口
- 接收方可以接收的数据范围
- 窗口大小取决于接收缓冲区的可用空间
- 通过窗口大小字段通知发送方
-
滑动窗口的工作原理
- 发送方根据窗口大小发送数据
- 接收方确认已接收的数据
- 发送方根据确认滑动窗口
超时重传
超时重传是TCP可靠传输的基本机制:
-
超时计时器
- 为每个发送的TCP段设置超时计时器
- 计时器到期但未收到确认,则重传数据
- 超时时间动态调整
-
超时时间的计算
- 基于往返时间(RTT)测量
- 使用加权平均计算平滑RTT(SRTT)
- 考虑RTT的变化(RTTVAR)
- 超时时间 = SRTT + 4 × RTTVAR
-
超时重传的问题
- 超时时间过长:延迟重传,降低效率
- 超时时间过短:不必要的重传,浪费资源
- 动态调整超时时间以适应网络变化
快速重传
快速重传是超时重传的补充机制:
-
触发条件
- 接收方收到乱序数据段
- 发送重复的ACK
- 发送方收到3个重复ACK,立即重传
-
快速重传的优势
- 不必等待超时
- 更快地检测和恢复丢包
- 提高传输效率
-
快速恢复
- 与快速重传配合使用
- 减小拥塞窗口而不是设置为1个MSS
- 避免网络性能急剧下降
选择确认(SACK)
选择确认是TCP的扩展机制,用于提高重传效率:
-
基本原理
- 接收方告知发送方已接收的不连续数据块
- 发送方只重传丢失的数据段
- 减少不必要的重传
-
SACK选项
- SACK许可:在连接建立时协商是否使用SACK
- SACK块:在ACK段中携带已接收的数据块信息
-
SACK的优势
- 提高重传效率
- 减少网络拥塞
- 提高吞吐量
TCP可靠传输的流程
-
发送方流程
- 数据分段
- 设置序列号
- 发送数据段
- 启动超时计时器
- 等待确认或重传
-
接收方流程
- 接收数据段
- 检查序列号
- 发送确认
- 交付数据给应用层
-
重传处理
- 检测丢包(超时或重复ACK)
- 重传丢失的数据段
- 调整拥塞窗口
TCP可靠传输的优化
-
延迟确认
- 接收方延迟发送ACK
- 希望有数据可以捎带确认
- 减少ACK段的数量
-
Nagle算法
- 减少小数据段的发送
- 收集小数据组成一个大数据段发送
- 提高网络利用率
-
窗口扩大
- 扩大窗口大小,提高吞吐量
- 适用于高延迟、高带宽网络
- 通过TCP选项协商
-
时间戳
- 用于测量往返时间(RTT)
- 防止序列号回绕导致的问题
- 提高超时重传的准确性
TCP可靠传输的问题与解决方案
-
乱序数据
- 问题:数据段到达顺序与发送顺序不一致
- 解决:接收方缓存乱序数据,等待缺失数据
- 优化:使用SACK告知发送方已接收的数据
-
重复数据
- 问题:相同的数据段被多次接收
- 解决:通过序列号检测和丢弃重复数据
- 优化:发送重复ACK告知发送方
-
数据丢失
- 问题:数据段在网络中丢失
- 解决:通过超时重传和快速重传恢复
- 优化:动态调整超时时间,提高重传效率
-
网络拥塞
- 问题:网络拥塞导致丢包增加
- 解决:通过拥塞控制机制调整发送速率
- 优化:使用快速恢复算法,避免性能急剧下降
TCP可靠传输的重要性
TCP可靠传输是TCP协议的核心价值:
- 确保数据的完整性,无丢失、无损坏
- 确保数据的顺序性,按序交付
- 适应各种网络环境,提供稳定的传输服务
- 为应用层提供可靠的数据传输基础
TCP流量控制
TCP流量控制是TCP协议的重要机制之一,用于管理发送方的发送速率,防止发送方发送数据过快导致接收方缓冲区溢出。流量控制通过滑动窗口机制实现,是点对点的控制机制,只涉及发送方和接收方。
流量控制的基本原理
-
滑动窗口
- 接收方通过窗口大小字段告知发送方可接收的数据量
- 发送方根据接收方通告的窗口大小控制发送速率
- 窗口大小动态调整,反映接收方的处理能力
-
接收缓冲区
- 接收方维护接收缓冲区,存储已接收但未处理的数据
- 缓冲区大小决定了接收方的处理能力
- 缓冲区可用空间决定了窗口大小
-
流量控制的目的
- 防止接收方缓冲区溢出
- 确保数据的可靠接收
- 适应不同处理能力的接收方
滑动窗口机制
-
发送窗口
- 发送方可以发送但未确认的数据范围
- 窗口大小由接收方通告
- 窗口可以滑动,随着数据的发送和确认而移动
-
接收窗口
- 接收方可以接收的数据范围
- 窗口大小取决于接收缓冲区的可用空间
- 通过窗口大小字段通知发送方
-
窗口滑动
- 发送方发送数据,窗口左边界向右移动
- 接收方确认数据,窗口右边界向右移动
- 窗口大小可以动态调整
流量控制的工作流程
-
初始窗口协商
- 连接建立时,双方通过TCP选项协商最大窗口大小
- 使用窗口扩大因子选项可以扩大窗口大小
- 初始窗口大小通常设置为接收缓冲区大小
-
窗口通告
- 接收方在每个ACK段中通告当前窗口大小
- 窗口大小反映接收缓冲区的可用空间
- 窗口大小为0表示接收方缓冲区已满
-
发送方调整
- 发送方根据接收方通告的窗口大小调整发送速率
- 发送方确保在途数据不超过接收方窗口大小
- 发送方可以发送的数据量 = min(拥塞窗口, 接收窗口)
零窗口处理
当接收方窗口大小为0时,需要特殊处理:
-
零窗口通告
- 接收方发送窗口大小为0的ACK段
- 告知发送方停止发送数据
- 发送方停止发送数据段
-
零窗口探测
- 发送方定期发送零窗口探测段
- 探测段包含1字节的数据
- 探测接收方窗口是否已更新
-
窗口更新
- 接收方处理完数据后,发送窗口更新ACK
- 窗口更新ACK可能丢失
- 零窗口探测确保发送方能及时获知窗口更新
流量控制与拥塞控制的区别
流量控制和拥塞控制是TCP中两个不同的机制:
| 特性 | 流量控制 | 拥塞控制 |
|---|---|---|
| 目的 | 防止接收方溢出 | 防止网络拥塞 |
| 对象 | 点对点(发送方-接收方) | 全局(整个网络路径) |
| 机制 | 滑动窗口 | 慢启动、拥塞避免、快速恢复 |
| 信息来源 | 接收方窗口通告 | 丢包、延迟等网络反馈 |
| 调整对象 | 发送速率 | 发送速率 |
流量控制的实现细节
-
窗口大小的计算
- 窗口大小 = 接收缓冲区大小 - 已接收未处理的数据量
- 接收方定期计算并通告窗口大小
- 窗口大小为0时停止发送数据
-
窗口更新的时机
- 接收方处理数据后立即发送ACK
- 可以延迟发送ACK以提高效率
- 窗口大小变化时必须发送ACK
-
窗口大小的限制
- 窗口大小字段为16位,最大65535字节
- 可以通过窗口扩大因子选项扩大窗口大小
- 窗口扩大因子最多可扩大14位,最大1GB窗口
流量控制的问题与解决方案
-
糊涂窗口综合症
- 问题:接收方通告很小的窗口,导致发送方发送小数据段
- 解决:接收方延迟通告窗口,直到窗口达到一定大小
- 优化:接收方在窗口大小达到MSS或缓冲区一半时才通告窗口
-
死锁
- 问题:发送方等待窗口更新,接收方等待数据到达
- 解决:发送方使用零窗口探测机制
- 优化:设置合理的零窗口探测间隔
-
窗口更新丢失
- 问题:携带窗口更新的ACK段丢失
- 解决:发送方通过零窗口探测获取窗口更新
- 优化:接收方重复发送窗口更新ACK
流量控制的优化
-
延迟确认
- 接收方延迟发送ACK
- 希望有数据可以捎带确认和窗口更新
- 减少ACK段的数量
-
窗口扩大
- 使用窗口扩大因子选项扩大窗口大小
- 适用于高延迟、高带宽网络
- 提高网络利用率
-
缓冲区管理
- 动态调整接收缓冲区大小
- 根据网络条件和应用需求优化
- 提高系统资源利用率
流量控制的应用场景
-
不同处理能力的设备
- 高性能服务器与低性能客户端通信
- 流量控制确保客户端不会被淹没
- 适应不同处理能力的设备
-
网络条件变化
- 网络拥塞导致传输延迟增加
- 流量控制自动调整发送速率
- 适应网络条件变化
-
应用程序处理速度变化
- 应用程序处理速度波动
- 流量控制确保数据不会丢失
- 适应应用程序处理速度变化
流量控制的重要性
TCP流量控制是确保可靠传输的关键机制:
- 防止接收方缓冲区溢出,避免数据丢失
- 适应不同处理能力的接收方,提高兼容性
- 与拥塞控制协同工作,优化网络性能
- 为应用层提供稳定的数据传输服务
TCP拥塞控制
TCP拥塞控制是TCP协议的核心机制之一,用于防止网络拥塞导致的性能下降。拥塞控制通过调整发送速率来适应网络条件,是TCP能够在互联网中稳定运行的关键。
拥塞控制的基本原理
-
拥塞窗口
- 发送方维护的窗口,限制在途数据量
- 拥塞窗口大小反映网络拥塞程度
- 发送方实际发送窗口 = min(拥塞窗口, 接收窗口)
-
拥塞检测
- 通过丢包检测网络拥塞
- 通过往返时间(RTT)变化检测拥塞
- 通过显式拥塞通知(ECN)检测拥塞
-
拥塞避免
- 慢启动阶段快速增加发送速率
- 拥塞避免阶段缓慢增加发送速率
- 检测到拥塞时快速降低发送速率
拥塞控制算法
TCP拥塞控制主要包括四个算法:
-
慢启动(Slow Start)
- 连接建立时,拥塞窗口初始化为1个MSS
- 每收到一个ACK,拥塞窗口增加1个MSS
- 拥塞窗口呈指数增长:1, 2, 4, 8, ...
- 当拥塞窗口达到慢启动阈值(ssthresh)时,进入拥塞避免阶段
-
拥塞避免(Congestion Avoidance)
- 拥塞窗口达到慢启动阈值后进入此阶段
- 每个RTT拥塞窗口增加1个MSS
- 拥塞窗口呈线性增长
- 更温和地探测网络可用带宽
-
快速重传(Fast Retransmit)
- 发送方收到3个重复ACK时触发
- 不必等待超时,立即重传丢失的数据段
- 快速检测和恢复丢包
- 进入快速恢复阶段
-
快速恢复(Fast Recovery)
- 与快速重传配合使用
- 将拥塞窗口减半,而不是设置为1个MSS
- 避免网络性能急剧下降
- 每收到一个重复ACK,拥塞窗口增加1个MSS
拥塞控制的状态转换
+-----------+
| 慢启动 |<----+
+-----------+ |
| 超时/重复ACK |
v |
+-----------+ |
| 拥塞避免 |-----+
+-----------+
| 3个重复ACK
v
+-----------+
| 快速恢复 |
+-----------+
| 超时
v
+-----------+
| 慢启动 |
+-----------+
拥塞控制的参数
-
拥塞窗口(cwnd)
- 发送方维护的窗口,限制在途数据量
- 初始值通常为1-10个MSS
- 根据网络条件动态调整
-
慢启动阈值(ssthresh)
- 从慢启动切换到拥塞避免的阈值
- 检测到拥塞时设置为当前拥塞窗口的一半
- 初始值通常设置为一个较大的值
-
往返时间(RTT)
- 数据从发送到接收确认的时间
- 用于计算超时时间
- 反映网络拥塞程度
TCP拥塞控制的演变
-
TCP Tahoe
- 早期TCP实现
- 包含慢启动、拥塞避免、快速重传
- 检测到拥塞时将拥塞窗口设置为1个MSS
-
TCP Reno
- 在Tahoe基础上增加快速恢复
- 检测到拥塞时将拥塞窗口减半
- 提高了网络性能
-
TCP NewReno
- 改进Reno的快速恢复算法
- 更好地处理多个丢包
- 提高了丢包恢复效率
-
TCP Vegas
- 基于延迟的拥塞控制算法
- 通过RTT变化检测拥塞
- 更主动地避免拥塞
现代TCP拥塞控制算法
-
CUBIC
- Linux默认的拥塞控制算法
- 基于三次函数的窗口增长
- 适用于高延迟、高带宽网络
-
BBR(Bottleneck Bandwidth and RTT)
- Google开发的拥塞控制算法
- 基于带宽和RTT测量
- 不依赖丢包作为拥塞信号
-
DCTCP(Datacenter TCP)
- 专为数据中心环境设计
- 使用显式拥塞通知(ECN)
- 适用于低延迟、高带宽环境
拥塞控制与流量控制的区别
拥塞控制和流量控制是TCP中两个不同的机制:
| 特性 | 拥塞控制 | 流量控制 |
|---|---|---|
| 目的 | 防止网络拥塞 | 防止接收方溢出 |
| 对象 | 全局(整个网络路径) | 点对点(发送方-接收方) |
| 机制 | 慢启动、拥塞避免、快速恢复 | 滑动窗口 |
| 信息来源 | 丢包、延迟等网络反馈 | 接收方窗口通告 |
| 调整对象 | 发送速率 | 发送速率 |
拥塞控制的问题与挑战
-
拥塞检测延迟
- 问题:拥塞发生到检测到有时间延迟
- 解决:使用更敏感的拥塞检测机制
- 优化:基于延迟的拥塞检测
-
公平性
- 问题:不同TCP流之间不公平竞争带宽
- 解决:设计更公平的拥塞控制算法
- 优化:考虑网络环境的公平性
-
高延迟、高带宽网络
- 问题:传统TCP算法在高速网络中性能不佳
- 解决:设计适用于高速网络的拥塞控制算法
- 优化:使用更大的初始窗口和更快的增长速率
-
无线网络
- 问题:无线网络丢包不一定是拥塞导致
- 解决:区分拥塞丢包和无线链路错误
- 优化:使用更智能的丢包处理机制
拥塞控制的优化
-
初始窗口优化
- 增大初始拥塞窗口(IW)
- RFC 6928建议初始窗口为10个MSS
- 减少慢启动时间,提高传输效率
-
快速打开(TCP Fast Open)
- 在SYN段中携带应用数据
- 减少连接建立时间
- 提高短连接的性能
-
显式拥塞通知(ECN)
- 路由器标记拥塞的数据包
- 接收方通过ECN-Echo告知发送方
- 发送方提前降低发送速率,避免丢包
-
延迟ACK优化
- 接收方延迟发送ACK
- 减少ACK段的数量
- 提高网络利用率
拥塞控制的重要性
TCP拥塞控制是互联网稳定运行的关键:
- 防止网络拥塞崩溃,确保网络稳定性
- 公平共享网络资源,提高网络利用率
- 适应各种网络环境,提供良好的性能
- 为应用层提供可靠、高效的数据传输服务