1 传输层概述
- 传输层主要负责主机中两个进程的通信,为端到端连接提供可靠传输服务。
1.1 传输层功能
- 为应用层提供服务,使用网络层的服务
- 提供进程与进程之间逻辑通信
- 复用和分用
- 复用:发送方多个应用进程使用同一个传输层协议发送数据
- 分用:接收方根据端口号将数据交给正确的应用进程
- 差错检测
1.2 传输层协议
- UDP:无连接的用户数据报协议
- TCP:有连接的传输控制协议
1.3 传输层的寻址与端口
- 端口:即传输层的服务访问点(TSAP)
- 数据链路层SAP是MAC地址
- 网络层SAP是IP地址
- 传输层SAP是端口
- 端口号
- 只有本地意义
- 端口号长度16比特,共65536个
- 套接字唯一标识了网络中的一台主机和它的一个进程。
2 UDP协议
- 在IP数据报基础上增加了复用、分用和差错检测功能
- UDP主要特点
- 无连接,减少开销和发送前的时延
- 尽最大努力交付,即不保证可靠交付
- 面向报文,一次传输一个报文
- 无拥塞控制,适合实时应用
- 首部开销小
2.1 UDP首部格式
-

-
源端口号(Source Port)
- 表示发送端端口号,字段长16位。
-
目标端口号(Destination Port)
- 表示接收端端口号,字段长度16位。
-
包长度(Length)
- 保存了UDP首部的长度和数据的长度之和,单位为字节。该字段长度16位。
- 一个UDP数据报可以发送的最大数据为 2^16 - 8 = 65528字节。
-
校验和(Checksum)
- 校验和是为了提供可靠的UDP首部和数据而设计。字段长度16位。
2.2 UDP校验
-
UDP的校验和是一个可选的错误检测机制,用于验证数据在传输过程中是否损坏。
-
这是 UDP 校验和最独特的设计------它包含了一个伪头部,该头部并不真正在网络中传输,仅用于校验和计算。
-
图示如下
-
计算内容包括三部分:
- 伪头部(12 字节,仅用于计算,不发送)。协议字段值为17,表示UDP协议。
- UDP 头部(8 字节,校验和字段本身先置 0)
- UDP 数据部分(若长度为奇数,末尾补一个 0 字节)
-
计算与验证过程
- 发送方计算:将上述内容视为一系列 16 位的字(每 2 字节为一组),对这些 16 位字进行二进制反码求和。如果在加法过程中最高位产生进位,需要将进位加到结果的最低位(称为"回卷"或 Wrap Around)。最后,将得到的 16 位结果按位取反(1变0,0变1),存入 UDP 首部的校验和字段1。
- 接收方验证:接收方使用完全相同的方法(伪首部 + UDP首部 + 数据)计算反码和。如果传输中没有发生任何错误,最终的计算结果应为全 1(即十六进制 0xFFFF)。如果不匹配,则说明数据在传输中受损,接收方会直接丢弃该数据报1。
-
抓一个UDP数据包看下,校验和为
0xF585 -
接下来分析下这个校验和如何计算出来的
*C0A8 0304 源IP地址(192.168.3.4) C0A8 0304 目的IP地址(192.168.3.4) 0011 全0+协议17 000D UDP总长度(13字节) 1F93 源端口号 (8083) 1F90 目的端口号(8080) 000D 包长度(13字节) 0000 校验和 6865 6C6C 6F00 数据 hello(末尾填0) -
接下来对上述数据进行相加
*0 + C0A8 = C0A8 +0304 → C0A8 + 0304 = C3AC +C0A8 → C3AC + C0A8 = 18454 → 拆成 1 和 8454 → 1 + 8454 = 8455 (回卷) +0304 → 8455 + 0304 = 8759 +0011 → 8759 + 0011 = 876A +000D → 876A + 000D = 8777 +1F93 → 8777 + 1F93 = A70A +1F90 → A70A + 1F90 = C69A +000D → C69A + 000D = C6A7 +0000 → C6A7 +6865 → C6A7 + 6865 = 12F0C → 低 16 位 2F0C,进位 1 → 2F0C + 1 = 2F0D +6C6C → 2F0D + 6C6C = 9B79 +6F00 → 9B79 + 6F00 = 10A79 → 低位 0A79,进位 1 → 0A79 + 1 = 0A7A -
对计算结果
0x0A7A进行取反得到最终校验和为0xF585
3 TCP协议
- TCP协议特点
- 面向连接的传输协议
- 提供可靠交付服务
- 无差错、不丢失、不重复、按序到达
- 提供全双工通信
- 面向字节流
3.1 TCP首部格式
-

-
源端口号(Source Port)
- 表示发送端端口号,字段长16位。
-
目标端口号(Destination Port)
- 表示接收端端口号,字段长度16位。
-
序列号(Sequence Number)
- 字段长32位。序列号是指发送数据的位置。每发送一次数据,就累加一次该数据字节数的大小。
-
确认应答号(Acknowledgement Number)
- 确认应答号字段长度32位。是指下一次应该收到的数据的序列号。
-
数据偏移(Data Offset)
- 该字段表示TCP所传输的数据部分应该从TCP包的哪个位开始计算,当然也可以把它看作TCP首部的长度。单位为4字节。
-
保留(Reserved)
- 该字段主要是为了以后扩展时使用,其长度为4位。
-
控制位(Control Flag)
- 字段长为8位,每一位从左至右分别为CWR、ECE、URG、ACK、PSH、RST、SYN、FIN。这些控制标志也叫做控制位。
- CWR(Congestion Window Reduced):CWR标志。
- ECE(ECN-Echo):ECE标志。
- URG(Urgent Flag):该位为1时,表示包中有需要紧急处理的数据。配合紧急指针使用。
- ACK(Acknowledgement Flag):该位为1时,确认应答的字段变为有效。TCP规定除了最初建立连接时的SYN包之外该位必须设置为1。
- PSH(Push Flag):该位为1时,表示需要将受到的数据立刻传给上层应用协议。PSH为0时,则不需要立即传而是先进行缓存。
- RST(Reset Flag):该位为1时表示TCP连接中出现异常必须强制断开连接。
- SYN(Synchronize Flag):用于建立连接。SYN为1表示希望建立连接,并在其序列号的字段进行序列号初始值的设定。
- FIN(Fin Flag):该位为1时,表示今后不会再有数据发送,希望断开连接。
-
窗口大小(Window Size)
- 该字段长为16位。简单理解就是允许对方发送的数据量。
-
校验和(Checksum)
- 跟UDP计算校验和的方式一样。唯一区别是伪首部的协议字段值伪6,表示TCP协议。
-
紧急指针(Urgent Pointer)
- URG为1时有意义。本报文段紧急数据字节数。
-
可选字段(Options)
- 选项字段用于提高TCP的传输性能。因为根据数据偏移(首部长度)进行控制,所以其长度最大为40字节。
3.2 TCP三次握手
- 连接过程
- 第一次握手
- 客户端发送连接请求,SYN置为1,同时发送一个序列号seq,值为x
- 第二次握手
- 服务端同意连接,ACK置为1,同时发送服务端的连接请求,SYN置为1
- 服务端还要回复确认应答号ack(对客户端序列号seq的回复),值为 x+1,同时客户端发送一个序列号seq,值为y
- 第三次握手
- 客户端同意连接,ACK置为1
- 客户端再回复确认应答号ack(对服务端序列号seq的回复),值为 y+1,同时客户端再发送一个序列号seq(表示下一个序号),值为x+1
- 抓包看下实际的握手过程

- 第一次握手
- 第二次握手
- 第三次握手
3.3 TCP四次挥手
- 挥手过程
- 第一次挥手
- 客户端发送关闭连接请求,FIN置为1,同时发送一个序列号seq,值为u
- 第二次挥手
- 服务端同意关闭连接,ACK置为1
- 服务端还要回复确认应答号ack(对客户端序列号seq的回复),值为 u+1,同时服务端发送一个序列号seq,值为v
- 第三次挥手
- 服务端发送关闭连接请求,FIN置为1
- 服务端再发送一个序列号seq,值为w
- 第四次挥手
- 客户端同意关闭连接,ACK置为1
- 客户端回复确认应答号ack(对服务端序列号seq的回复),值为w+1
- 抓包看下实际挥手过程
-

-
第一次挥手
-
第二次挥手
-
第三次挥手
-
第四次挥手
-
3.4 TCP可靠传输
- TCP通过以下四点来实现数据的可靠传输
- 校验和:每个TCP报文段都包含一个校验和,用于检测数据在传输过程中是否发生比特错误。如果接收端计算出的校验和与报文中的不一致,就会丢弃该报文段,并不发送确认(ACK),等待发送方超时重传。
- 序列号:TCP为每个数据字节分配一个序列号。接收端利用序列号对数据进行排序,并去除重复的报文段,保证数据按发送顺序交付给应用层。
- 确认应答号:接收端收到数据后,会向发送端返回确认(ACK),指明下一个期望收到的序列号。如果发送端在一定时间内没有收到确认,则会认为数据丢失,并进行重传。
- 重传 :TCP提供两种重传的机制,一种是基于时间的超时重传,一种是基于接收端反馈消息的快速重传。相比之下前者占用更少的网络带宽,但是效率很低。而后者则相反。
- 超时重传:如果发送端等待接收端发送ACK超过了TCP所设置的超时时间,那么此时发送端便会重传刚发的数据包。
- 快速重传:快速重传不会等待计时器变为超时,如果发现乱序、或者是丢失的数据包便会立即ACK,一旦发送端接收到的重复ACK数目超过重复ACK阈值(一般为3),便会诱发快速重传机制。
- 数据传输示例
- 抓包看下具体传输过程
- 客户端发送hello server消息
- 服务端进行回复
- 服务端发送welcome connect消息
- 客户端进行回复
- 客户端发送hello server消息
3.5 TCP流量控制
- TCP的流量控制是一种端到端的机制,目的是防止发送方发送数据过快,导致接收方的应用程序来不及处理,从而造成接收方缓冲区溢出和数据丢失。
- 流量控制的基本方法就是接收方根据自己的接收能力控制发送方地发送速率。
- 核心机制:TCP利用滑动窗口机制实现对发送方地流量控制。
- 工作流程示例:
- 连接建立时,接收方通告自己的初始接收窗口rwnd(如 4096 字节)。
- 发送方最多发送 4096 字节未确认数据。
- 接收方收到数据后,应用程序不断从缓冲区读取数据。假设应用读走了 2048 字节,缓冲区空出 2048 字节,接收方就会在下一个 ACK 中通告窗口更新为 2048。
- 如果应用读取很慢,缓冲区快满了,接收方会通告一个很小的窗口,甚至为 0。
- 发送方严格按通告窗口发送,从而不会淹没接收方。
- 零窗口与持续计时器
- 当接收方缓冲区完全填满,它会通告窗口大小为 0,要求发送方停止发送数据。这被称为零窗口。
- 问题:如果接收方在缓冲区清空后,发送一个"窗口非零"的通告,但这个通告在网络上丢失了,那么发送方会永远等待,接收方也在等待新数据,造成死锁。
- 解决方案------持续计时器:发送方在收到零窗口通告后,会启动一个持续计时器。计时器超时后,发送方主动发送一个很小的窗口探测包(一般只含 1 字节数据),询问接收方窗口是否已变大。接收方回复当前窗口大小,从而打破死锁。
3.6 TCP拥塞控制
-
防止过多数据注入网络,保证路由器和链路不过载。
-
TCP拥塞控制通过慢开始、拥塞避免、快重传、快恢复来实现拥塞控制。
-
慢开始和拥塞避免是1988年就提出的两种TCP拥塞控制算法,也就是TCP的Tahoe版本。1990年又增加了两个新的拥塞控制算法以便改进TCP的性能,这就是快重传和快恢复,被称为TCP的Reno版本。
-
图示如下
-
慢启动
- 初始状态下,拥塞窗口
cwnd通常为 1 个 MSS(最大报文段长度)。每收到一个 新的 ACK,拥塞窗口cwnd就增加 1 个 MSS。这意味着每经过一个 RTT,拥塞窗口会翻倍(指数增长)。 - 当拥塞窗口
cwnd超过慢启动门限ssthresh就会进入拥塞避免算法。
- 初始状态下,拥塞窗口
-
拥塞避免
- 每收到一个 新的 ACK,拥塞窗口增加 1 / 拥塞窗口 个 MSS。这在实际效果上等同于每经过一个 RTT,拥塞窗口增加 1 个 MSS(线性增长,加法增大)。
- 随着拥塞窗口线性增大,肯定会出现网络拥塞,就会出现丢包现象。出现丢包就会触发重传机制。重传包括超时重传和快速重传。
-
快速重传
- 触发超时重传时,慢开始门限
ssthresh设为原来拥塞窗口cwnd的一半,再将cwnd设为1。重新开始慢启动,如图中虚线所示。但这样会降低传输效率。 - 快速重传,不是等待超时重传计时器超时再重传,而是发送方收到三个相同的重复ACK时,触发快速重传机制。
- 触发超时重传时,慢开始门限
-
快恢复
- 快恢复算法配合快重传算法使用,发送方将慢开始门限
ssthresh的值和拥塞窗口cwnd的值都调整为当前cwnd值的一半,并开始执行拥塞避免算法。这样不用走图中虚线部分,就提高了传输效率。
- 快恢复算法配合快重传算法使用,发送方将慢开始门限
3.7 TCP流量控制和拥塞控制区别
| 维度 | 流量控制 | 拥塞控制 |
|---|---|---|
| 核心目标 | 防止接收方缓冲区溢出,确保接收方应用能及时处理数据 | 防止网络中间节点(路由器)缓存溢出,避免或缓解网络拥塞 |
| 作用对象 | 端到端(发送方------接收方) | 整个网络路径(发送方------路由器------接收方) |
| 决策依据 | 接收方通告的接收窗口(rwnd) | 发送方自己估算的拥塞窗口(cwnd) |
| 窗口决定 | rwnd 由接收方当前可用缓冲区大小决定 | cwnd 由发送方根据网络丢包、延迟等信号动态调整 |
| 实际发送上限 | min(rwnd, cwnd) | min(rwnd, cwnd) |
| 触发场景 | 接收方处理速度 < 发送方发送速度 | 网络带宽不足、路由器队列积压、丢包 |
| 主要机制 | 滑动窗口、零窗口探测 | 慢启动、拥塞避免、快速重传、快速恢复 |
| 对发送方的意义 | 强制停止:接收方说停就必须停 | 主动减缓:发送方根据网络信号主动降速 |

















