2310 字
12 分钟
TCP
2024-07-29

Transport Control Protocol#

特点#

  • TCP是面向连接(虚连接 对比电路交换虚电路)的传输层协议
    • 只有建立了连接才能开始通信
    • 连接是逻辑连接,不是实际链路
  • 每一条TCP连接只能有两个端点,每一条TCP连接只能是点对点
    • 无法用于广播
  • TCP提供可靠交付的服务,无差错、不丢失、不重复、按序到达
  • TCP提供全双工通信
    • 发送缓存
      • 准备发送的数据
      • 已发送但尚未收到确认的数据
    • 接收缓存
      • 按序到达但尚未被接受应用程序读取的数据
      • 不按序到达的数据
  • TCP字节流交付给上层(对比UDP按报文交付给应用层)
    • TCP把应用程序交下来的数据看成仅仅是一连串的无结构的字节流
    • TCP将要传输的数据分成多个字节,以字节为单位传送

首部格式#

Pasted image 20240729175744

  • 源端口 目标端口
  • 序号 此报文段中所发送数据的第一个字节的序号
    • 在一个TCP连接中传送的字节流中的每一个字节都按顺序编号,而可靠传输机制中所介绍的是每一个报文一个编号
  • 确认号ack(32位,4B):期望收到对方下一个报文段第一个数据字节的序号
  • 数据偏移(4bit):以4B为单位,数据部分从哪个偏移处开始,即首部长度
  • 控制位
    • 紧急位URG:为1时,表示该报文中有紧急数据紧急指针有效,需要优先从TCP缓存队列中发送
    • 确认位ACK:为1时,确认号才有效
    • 推送位PSH:为1时,接收方尽快将消息交付到上层,不再等待缓冲区填满后才交付,如交互式网络应用
    • 复位RST:为1时,表示必须释放连接,然后再重新建立传输链接
    • 同步位SYN:为1时,表示这个报文是一个建立连接的请求/接收报文
    • 终止位FIN:为1时,表示此报文段发送方数据已发完,要求释放连接
  • 窗口(16位,2B):单位为字节(B),表示己方的接收窗口大小,即允许对方发送的数据量(0∼216−10∼216−1)
  • 检验和 校验和
  • 紧急指针(16位,2B):URG=1时才有意义,表明本报文中紧急数据的字节数
    • 紧急数据从0开始
    • 实际上指向的是紧急数据尾部的位置
  • 选项(长度可变):最大报文段长度MSS、窗口扩大、时间戳、选择确认
  • 填充:使TCP首部长度为4B的整数倍

TCP分段(片)#

三次握手#

sequenceDiagram Client ->> Server: SYN = 1, seq = x Server ->> Client: SYN = 1, ACK = 1, seq = y, ack = x + 1 Client ->> Server: SYN = 0, ACK = 1, seq = x + 1, ack = y + 1
  • xy都是随机生成的数字
  • 前两次握手虽然没有携带任何数据但是都需要消耗一个序号,ack向前推进
  • 第三次握手可以捎带数据
  • server收到第一个连接后进入半连接状态 如果一直发送第一次握手的SYN数据包,并不进行确认,导致服务器有大量挂起等待确认的TCP连接,消耗CPU和内存,进而导致死机
  • 为什么是三次握手?
    • 能防止历史连接的建立
    • 能减少双方不必要的资源开销
    • 能帮助双方同步初始化序列号
    • 「两次握手」:无法防止历史连接的建立,会造成双方资源的浪费,也无法可靠的同步双方序列号;
    • 「四次握手」:三次握手就已经理论上最少可靠连接建立,所以不需要使用更多的通信次数。

四次挥手#

Pasted image 20240729194819

  • 客户端发送连接释放报文段,停止发送数据,主动关闭TCP连接,转为FIN-WAIT-1状态
  • 服务器端回送一个确认报文段,并转为CLOSE-WAIT状态;客户到服务器这个方向的连接就释放了(半关闭状态),客户端收到这个确认段后转为FIN-WAIT-2状态
    • 对于客户端的fin报文要消耗掉一个ack
  • 服务器端发完数据,就发出连接释放报文段,主动关闭TCP连接,转为LAST-ACK状态
  • 客户端回送一个确认报文段,转为TIME-WAIT状态,再等到时间等待计时器设置的2MSL(最长报文段寿命)后,连接彻底关闭
    • 对于服务器的fin报文要消耗掉一个ack
  • fin报文要消耗掉一个ack
  • 2MSL的意义:防止服务器端因为未收到客户端的确认报文段导致无法关闭 如果第四次挥手丢包了怎么办呢
  • 客户机释放的最短时间是RTT+2MSLRTT+2MSL,服务器最短的释放时间是1.5RTT1.5RTT
  • FIN报文段能够捎带数据,但一般不这样做

保活机制#

  • 保活计时器

TCP可靠传输#

  1. 可靠传输机制
  2. 校验 与UDP类似,通过伪首部进行检验和校验
  3. 序号 为传输流中的每一个字节进行编号,将缓冲区中的字节组成若干个TCP段(数据报),通过确认号和序号的机制进行发送
  4. 确认 接收方收到报文段后,返回确认字段,确认字段中的确认号为下一个期望收到的起始字节编号。采用捎带确认与累计确认
  5. 重传
  • 超时重传:TCP的发送方在规定的时间(重传时间RTTs)内没有收到确认就要重传已发送的报文段,RTTs是动态计算得到的 重传时间过短:太长的数据报来不及发送完毕 重传时间过长:增加网络空闲时间,降低传输效率
  • 冗余ACK(冗余确认) 每当比期望序号大的失序报文段到达时,发送一个冗余ACK,指明下一个期待字节的序号

流量控制#

TCP利用滑动窗口机制实现流量控制。 接收方根据自己的缓冲区大小,动态的通过窗口字段调整发送方发送窗口的大小。 发送方窗口大小取接收窗口rwnd和拥塞窗口cwnd的最小值 拥塞窗口:发送方根据自己估算的网络拥塞程度而设置的窗口值,反映网络当前容量 当接收方通过确认重传机制进行字节编号确认时,会连带着修改发送方的允许发送窗口大小 TCP为每一个连接设有一个持续计时器,只要TCP连接的一方收到对方的零窗口通知,就启动持续计时器。到时间则发送一个零窗口探测报文段,并重置计时器时间。

拥塞控制#

假设接收窗口非常大,那么我们就不用考虑接收方,而只去考虑对链路拥塞的影响

慢开始和拥塞避免#

Pasted image 20240729201709

  • cwnd的单位是报文段
  • 默认的初始值为1(或MSS长度)
  • 传输轮次:从发送一批报文段到收到它们的确认所用的时间,单位为往返时延RTT
  • 慢开始:cwnd的增加速度为指数型增长,起始为1
    • 当某个RTT开始时的 2cwnd>ssthresh2cwnd \gt ssthresh时,不采用指数增长,下个RTT开始时的cwnd=sstresh
  • 拥塞避免:当cwnd的值达到慢开始门限ssthresh时,增长模式变为每次+1
  • 网络发生拥塞
    • cwnd置为1,重新进入慢开始算法
    • 将ssthresh置为当前cwnd的一半,提前进入拥塞避免算法

快重传和快恢复#

Pasted image 20240729201848

  • 快重传:采用冗余ACK机制,当收到3次连续的冗余ACK时执行快重传,重新发送丢失帧
  • 新的ssthresh为发生拥塞时cwnd的一半
  • 快恢复:当发送拥塞时,只需要将窗口降低到新的慢开始门限ssthresh,再次进入拥塞避免算法即可

其他#

TCP的四种计时器#

区分连接报文段与数据报文段#

最大带宽#

序号/RTT

题目#

tmp16