跳到主要内容

TCP&UDP

TCP&UDP 是运输层两个主要协议。根据所使用的的协议是 TCP 或 UDP,分别称之为 TCP 报文段或 UDP 用户数据报

UDP

用户数据报协议 UDP:在传送数据之前不需要先建立连接。特点如下:

  • 无连接的
  • 尽最大努力交付
  • 面向报文
  • 没有拥塞控制
  • 支持一对一、一对多、多对一和多对多的交互通信
  • 首部开销小,只有 8 个字节,比 TCP 的 20 个字节的首部要断

TCP

传输控制协议 TCP: 提供面向连接的服务。特点如下:

  • 面向连接
  • 点对点
  • 可靠交付
  • 双全工通信
  • 面向字节流

重传机制

在 TCP 中,当发送端的数据到达接收主机是,接收端主机会返回一个确认应答的消息,表示已收到消息。如何在错综复杂的网络,保证正常的数据传输? TCP 针对数据包丢失的情况,会用重传机制解决。

  • 超时重传:在发送数据是,设定一个定时器,当超过指定时间后,没有收到对方的 ACK 确认应答报文,就会重发该数据
  • 快速重传:当收到三个相同的 ACK 报文时,会在定时器过期之前,重传丢失的报文
  • SACK:在 TCP 头部选项字段里加一个 SACK,它可以缓存的地图发送给发送方,这样发送方就知道那些数据没接到,就可以重传丢失的数据
  • D-SACK:主要使用了 SACK 告诉发送方有哪些数据被重复接收了

滑动窗口

TCP 是全双工的,所有发送端有发送缓存区,接收端有接收缓存区。发送方在等到确认应答返回之前,必须在缓冲区保留已发送的数据。如果按期收到应答,此时数据就可以从缓存区清除

流量控制

让发送方的发送速率不要太快,要让接收方来得及接收。TCP 提供了一种机制可以让发送方根据接收方的实际接收能力控制发送的数据量。

在建立连接时,接收端会告诉发送端自己的窗口大小(rwnd),每次接收端收到数据后都会再次确认(rwnd)大小。如果值为 0,停止发送数据。此时会出现死锁现象。为避免此问题,TCP 会为每个连接设有一个持续定时器,只要 TCP 连接一方收到对方的零窗口通知,就启动持续计时器。如果持续计时器超时,就会发送窗口探测报文。

{/ 如果接收方腾出几个字节并告诉发送方现在有几个字节的窗口,而发送方会义无反顾的发送这几个字节,这就是糊涂窗口综合症。 /}

拥塞控制

防止过多的数据注入网络中,这样可以使网络汇总的路由器或链路不至过载。

拥塞窗口 cwnd:发送方维护的一个状态变量,根据网络的拥塞程度动态变化的,只要发送方没有在规定时间内接收到 ACK 应答报文,也就是发送了超时重传,就会认为网络出现了拥塞。将窗口变小。发送方让自己的发送窗口等于拥塞窗口

拥塞控制主要四个算法:

  • 慢启动:当发送方开始发送数据时,由小到大逐渐增大发送窗口,也就是说,由小到大逐渐增大拥塞窗口数值
    • 当发送方每收到一个 ACK,拥塞窗口 cwnd 的大小就会加 1
  • 拥塞避免:当拥塞窗口 cwnd 超过慢启动门限 ssthresh 就会进行拥塞避免算法。将原本的慢启动算法的指数增长变成了线性增长
    • 每接收一个 ACK 时,cwnd 增加 1/cwnd
  • 拥塞发生:当网络出现拥塞,也就是发生数据包重传,重传机制主要有两种:超时重传、快速重传
    • 发生超时重传,将 ssthresh 设为 cwnd/2 cwnd 重置为 1
  • 快速恢复:一般与快速重传同时使用,快速恢复算法认为,还能收到三个重复 ACK 说明网络没有那么糟糕,所以没有必要向超时那么强烈
    • cwnd 设置 cwnd/2, ssthresh = cwnd

ssthresh 慢启动门限

  • cwnd < ssthresh(慢启动门限) 使用慢开始算法
  • cwnd > ssthresh 使用拥塞避免算法

连接管理

TCP 是面向连接的协议。TCP 运输连接的建立和释放是每一次面向连接的通信必不可少的过程。因此,运输连接就有三个阶段,即:连接建立数据传送连接释放

TCP 连接的建立(三次握手)

  • 最初,客户端 A 和服务端 B 的 TCP 进程都是处于 CLOSE(关闭)状态。一开始服务端 B 准备接收客户进程的连接请求,处于 LISTEN(收听)状态,等待客户的连接请求。
  • 客户端 A 向 B 发出连接请求报文段,这是首部中的同步位 SYN = 1,同时选择一个初始序号 seq=x。客户进程进入 SYN-SENT(同步已发送)状态。
  • B 收到连接请求报文段后,如同意连接,则向 A 发送确认。在确认报文段中应把 SYN 位和 ACK 位都置 1,确认号是 ack = x + 1,同时也为自己选择一个初始序号 seq=y。服务端进程进入 SYN-RCVD(同步收到)状态。
  • A 收到 B 的确认后,还要向 B 给出确认。确认报文段的 ACK 置 1,确认号 ack = y +1,而自己的序号 seq = x + 1。这是 TCP 连接已建立,A 也进入 ESTABLISHED(已建立连接)状态。
注意

TCP 规定,SYN 报文段(即 SYN=1 的报文段)不能携带数据。因此前两次握手是不允许携带数据。第三次握手可以携带数据

三次握手的原因
  • 为了防止旧的重复连接初始造成混乱是首要原因
  • 避免资源浪费
  • 同步双发初始化序列号

TCP 连接断开

  • 数据传输结束后,双方都可以释放连接。客户端 A 打算关闭,发送报文段 FIN=1 seq=u,进入 FIN-WAIT-1 状态,等待 B 确认
  • B 收到断开报文后发出确认,ack = u + 1,进入 CLOSE-WATI 状态。
  • A 收到 B 的确认,进入 FIN-WAIT-2 状态,等待 B 发出的连接释放报文段。
  • 若 B 没有要向 A 发送的数据,发送报文段 FIN=1,ack = u + 1,进入 LSAT-ACK 状态
  • A 收到 B 的连接释放报文段后,对此发去确认。ACK=1,seq=w+1,seq=u+1。进入 TIME-WAIT 状态。等待 2MSL 计时器
  • B 收到了 A 的确认,进入 CLOSE 状态
四次挥手的原因
  • 关闭连接是,客户端向服务端发送 FIN 时,仅仅表示客户端不在发送数据了但是还能接受数据
  • 服务端接收客户端的 FIN 报文时,先回一个 ACK 应答报文,而服务端可能还有数据需要处理和发送,等服务端不在发送数据时,才发送 FIN 报文给客户端来表示同意现在关闭连接