本文旨在帮助大家了解目前常用的传输层协议:UDP协议,TCP协议;并简单对比两者的特点;欢迎看官老爷留言。

UDP协议

UDP协议,全称是 User Datagram Protocol,用户数据报协议。

我们首先了解一下该协议的格式,如下图所示:

image.png

  • Source Port : 源端口,16位

  • Destination Port : 目标端口,16位

  • Length:消息体长度,16位

  • Checksum:检验为,16位

  • Data octets:一个字节一个字节的数据。Octet是8位

首先不要感到惊讶,这就是大名鼎鼎的UDP协议,它的格式就是这么简单清晰。

它的特点是:

  • 协议简洁

  • 快,传输过程不需要握手

  • 非面向连接

  • 不保证可靠传输

  • 无序

  • 适合广播

你可能直观的可以感觉到格式是挺简洁的,但是你说的 可靠性差,无序,适合广播又是哪里体现出来的呢?

别着急,我们在对比看看TCP协议的格式,对比一下你就会有深入的理解了。

TCP协议

TCP 协议,全称是 Transmission Control Protocol 传输控制协议。

同样的我们先了解一下报文格式:

image.png

  • Source Port : 源端口,16位

  • Destination Port : 目标端口,16位

  • Sequence Number: 序列码,32位

  • Acknowledgment Number:应答码,32位

  • Data Offset:偏移量,4位;指头的大小

  • Reserver: 保留位,6位

  • 标志位,6位;URG,ACK,PSH,RST,SYN,FIN

  • Window: 窗口,16位

  • Checksum : 校验位,16位

  • Urgent Pointer: 紧急指针,16位

  • Options:选项,长度不定,但必须是整字节,所以会有Padding补齐

  • Data:数据域

看过这么复杂的结构,瞬间感觉UDP“真香呀”,不过TCP协议的强大能力也得益于其精巧的报文设计。

它具备如下这些特点:

  • 面向连接,TCP建立连接的时候需要三次握手,具体了解该过程,可以移步笔者的聊聊TCP协议的三次握手和四次挥手

  • 传输有序性,我们可以看到报文结构中有一对收发的序列号,TCP正式通过它来保证顺序性的。

  • 流量控制,TCP协议的发送方通过接收方反馈的窗口大小可以达到流量控制的目的

  • 不适广播场景,同样的因为TCP在建立连接的过程中需要三次握手,如果用于广播场景会消耗相对较多的流量,所以不适合用于广播场景

  • 拥塞控制

经过这样的一对比,才发现还真是“高级呀”。

对比

image.png

TCP是如何实现拥塞控制的

网络传输过程中,某段时间如果网络中某一资源的需求超过了该资源所能提供的可用部分,网络性能就会变坏,这种情况就叫做网络拥塞
为解决这个问题,TCP中使用了四种拥塞控制算法

  • 慢开始
  • 拥塞避免
  • 快重传
  • 快恢复

慢开始

发送方会维持一个拥塞窗口cwnd的变量,拥塞窗口的大小有网络拥塞的情况来决定;并且会在收发包过程中动态的进行变化。发送方会让本端的发送窗口等于拥塞窗口。

慢开始的核心思想:指数级由小到大逐渐增加拥塞窗口大小,如果网络出现阻塞,拥塞窗口就减小。

判断出现网络拥塞的依据:没有按时收到应当到达的确认报文(即发生重传)。
维护一个慢开始门限ssthresh状态变量:

当cwnd < ssthresh 时,使用慢开始算法。

当cwnd > ssthresh 时,停止使用慢开始算法而改用拥塞避免算法。

当cwnd = ssthresh 时,既可以使用慢开始算法,也可以使用拥塞避免算法。

假设发送方拥塞窗口cwnd的值为1,发送窗口swnd等于拥塞窗口cwnd,那么目前发送方只能发送一个报文段,cwnd为几就能发送几个报文段,接收方收到报文段后发送回复确认,发送方收到确认报文,会将拥塞窗口的值乘2,变为2。
发送方此时一次就能发送两个报文段,接收方收到报文段后返回两次确认报文段,发送方收到之后拥塞窗口再乘2,cwnd=4。知道发送方发送16个报文段都按时收到确认报文,拥塞窗口变为32,但是这一次没有按时收到确认报文,即有报文需要重传,表示网络发生了拥塞,这时候设定ssthresh为当前窗口cwnd的一半,即ssthresh = cwnd/2 = 16。重新进行慢开始。再一次cwnd=16的时候,开启拥塞避免算法。

拥塞避免

慢开始达到门限值ssthresh时,会直线拥塞避免算法,拥塞窗口cwnd,每次不在加倍增长,而是每次缓慢递增,线性增长。

不管是慢开始还是拥塞避免算法,只要发生网络拥塞的情况,就会讲ssthresh变为当前cwnd的一半,然后重新执行慢开始算法。

image-1676512347726

快速重传

起初的TCP只有慢开始和拥塞避免,没有快重传和快恢复。1990年以后才支持快重传和快恢复。快速恢复时如何执行的呢?

考虑下面这种情况,在数据传送过程中,网络有可能不太稳定,个别报文段在网络中丢失了,但是实际上网络并没有发生拥塞。这样会导致发送方超时重传,误以为网络上发生了拥塞,由于有慢开始和拥塞避免机制,发送方错误的启动了慢开始算法,并且把拥塞窗口cwnd又设置为最小值1,因为降低了传输效率。

所以引入快速重传的机制是为了避免丢包等情况,带来的网络拥塞误判,使得发送能力降低。

为解决这个问题,快重传要求接收方在收到一个失序的报文段后立即发出重复确认,为的是让发送方知道有一个报文丢失了,快速重传算法规定,发送方只要一连收到三个重复确认就应当立即重传对方还没有接收到的报文段,而不必继续等待设置的重传计时器时间到期。

image-1676512543252

快速恢复

快速恢复算法是配合快速重传算法使用的,流程如下:

image-1676512635149

(1)当发送方连续收到三个重复确认的时候,执行“乘法减小”算法,将ssthresh门限减半(为了预防网络发生拥塞),但是接下来不执行慢开始算法,因为如果网络发生拥塞的话就不会收到好几个重复的确认,所以发送方现在认为网络可能没有出现拥塞。
(2)此时不会执行慢开始算法,而是将拥塞窗口cwnd设置为ssthresh减半后的值,然后执行拥塞避免算法,让cwnd缓慢变大。