面试官:TCP和UDP的区别?我:面向连接和面无连接...

TCP和UDP都是传输层协议,TCP面向连接,UDP无连接,TCP传输前需要三次握手建立连接,传输结束需要四次挥手结束连接,而UDP不建立连接直接传输数据报文;TCP可靠,因为TCP通过序列号、确认应答、超时重传、错误校验等机制保证数据的完整性和顺序,而UDP不可靠,没有复杂的确认和重传机制,因此传输速度高于TCP,对于时效性要求高,准确性要求低的场景适合使用UDP,而TCP主要用于高可靠性的场景。

TCP的特点和应用场景:

  1. 面向连接:在数据传输前,TCP需要通过三次握手建立连接,确保两端准备好通信。
  2. 可靠性:TCP提供可靠的数据传输,通过序列号、确认应答、超时重传、错误校验等机制保证数据的完整性和顺序。
  3. 流量控制:利用滑动窗口机制,TCP可以动态调整发送速率,以避免拥塞和数据丢失。
  4. 拥塞控制:在检测到网络拥塞时,TCP会减少数据的发送速率。
  5. 有序传输:确保数据按照发送顺序到达接收端。
  6. 应用场景:适用于需要高可靠性的场景,如Web浏览(HTTP)、电子邮件(SMTP、POP3)、文件传输(FTP)、在线交易等。

UDP的特点和应用场景:

  1. 无连接:UDP不建立连接,直接发送数据报文,减少了建立和维护连接的开销。
  2. 速度快:由于没有复杂的确认和重传机制,UDP传输速度通常比TCP快。
  3. 头部开销小:UDP头部只有8字节,而TCP头部至少20字节,更适合小数据包传输。
  4. 不可靠传输:UDP不保证数据的可靠到达,不进行错误恢复,可能丢包、乱序。
  5. 无拥塞控制:UDP不会根据网络状况调整发送速率,可能会加剧网络拥塞。
  6. 应用场景:适用于实时性要求高但能容忍一定数据丢失的场景,如在线游戏、VoIP、视频流、即时消息、广播或多播服务等。

总结

1.UDP和TCP协议的主要区别是两者在如何实现信息的可靠传递方面不同。

TCP协议中包含了专门的传递保证机制,当数据接收方收到发送方传来的信息时,会自动向发送方发出确认消息;发送方只有在接收到该确认消息之后才继续传送其它信息,否则将一直等待直到收到确认信息为止。 与TCP不同,UDP协议并不提供数据传送的保证机制。如果在从发送方到接收方的传递过程中出现数据报的丢失,协议本身并不能做出任何检测或提示。因此,通常人们把UDP协议称为不可靠的传输协议。

2.相对于TCP协议,UDP协议的另外一个不同之处在于如何接收突发性的多个数据报。

不同于TCP,UDP并不能确保数据的发送和接收顺序。事实上,UDP协议的这种乱序性基本上很少出现,通常只会在网络非常拥挤的情况下才有可能发生。 

    既然UDP是一种不可靠的网络协议,那么还有什么使用价值或必要呢?其实不然,在有些情况下UDP协议可能会变得非常有用。因为UDP具有TCP所望尘莫及的速度优势。虽然TCP协议中植入了各种安全保障功能,但是在实际执行的过程中会占用大量的系统开销,无疑使速度受到严重的影响。反观UDP由于排除了信息可靠传递机制,将安全和排序等功能移交给上层应用来完成,极大降低了执行时间,使速度得到了保证。

DNS同时占用TCP、UDP端口53.

DNS使用TCP:

1.报文超长

当解析器发出一个request后,返回的response中的tc删节标志比特位被置1时,说明反馈报文因为超长而有删节。这是因为UDP的报文最大长度为512字节。解析器发现后,将使用TCP重发request,TCP允许报文长度超过512字节。既然TCP能将data stream分成多个segment,它就能用更多的segment来传送任意长度的数据。

2.区域传送

DNS的规范规定了2种类型的DNS服务器,一个叫主DNS服务器,一个叫辅助DNS服务器。在一个区中主DNS服务器从自己本机的数据文件中读取该区的DNS数据信息,而辅助DNS服务器则从区的主DNS服务器中读取该区的DNS数据信息。当一个辅助DNS服务器启动时,它需要与主DNS服务器通信,并加载数据信息,这就叫做区传送(zone transfer)。除此之外,辅域名服务器也会定时(一般时3小时)向主域名服务器PDS进行查询以便了解数据是否有变动。如有变动,也会执行一次区域传送。区域传送将使用TCP而不是UDP,因为传送的数据量比一个request或response多得多。

DNS使用UDP: 

客户端向DNS服务器查询域名,一般返回的内容都不超过512字节,用UDP传输即可。不用经过TCP三次握手,这样DNS服务器负载更低,响应更快。虽然从理论上说,客户端也可以指定向DNS服务器查询的时候使用TCP,但事实上,很多DNS服务器进行配置的时候,仅支持UDP查询包。 解析器还是服务端都必须自己处理重传和超时。DNS往往需要跨越广域网或互联网,分组丢失率和往返时间的不确定性要更大些,这对于DNS客户端来说是个考验,好的重传和超时检测就显得更重要了。

使用TCP和UDP的情况分析

当数据传输的性能必须让位于数据传输的完整性、可控制性和可靠性时,TCP协议是当然的选择。当强调传输性能而不是传输的完整性时,如:音频和多媒体应用,UDP是最好的选择。在数据传输时间很短,以至于此前的连接过程成为整个流量主体的情况下,UDP也是一个好的选择,如:DNS交换。把SNMP建立在UDP上的部分原因是设计者认为当发生网络阻塞时,UDP较低的开销使其有更好的机会去传送管理数据。TCP丰富的功能有时会导致不可预料的性能低下,但是我们相信在不远的将来,TCP可靠的点对点连接将会用于绝大多数的网络应用。

TCP握手和挥手状态

TCP首部:

- 序号  :用于对字节流进行编号,例如序号为 301,表示第一个字节的编号为 301,如果携带的数据长度为 100 字节,那么下一个报文段的序号应为 401。

- 确认号  :期望收到的下一个报文段的序号。例如 B 正确收到 A 发送来的一个报文段,序号为 501,携带的数据长度为 200 字节,因此 B 期望下一个报文段的序号为 701,B 发送给 A 的确认报文段中确认号就为 701。

- 数据偏移  :指的是数据部分距离报文段起始处的偏移量,实际上指的是首部的长度。

- 确认 ACK  :当 ACK=1 时确认号字段有效,否则无效。TCP 规定,在连接建立后所有传送的报文段都必须把 ACK 置 1。

- 同步 SYN  :在连接建立时用来同步序号。当 SYN=1,ACK=0 时表示这是一个连接请求报文段。若对方同意建立连接,则响应报文中 SYN=1,ACK=1。

- 终止 FIN  :用来释放一个连接,当 FIN=1 时,表示此报文段的发送方的数据已发送完毕,并要求释放运输连接,发送FIN后,只接收,不发送。

- 窗口  :窗口值作为接收方让发送方设置其发送窗口的依据。之所以要有这个限制,是因为接收方的数据缓存空间是有限的。

建立连接后,确认标志位ACK都重置为1,确认序列号ack=接收端期望从发送端接收到的下一个字节的序列号=接收到的seq+1。

 

 

在进入CLOSING状态后,只要收到了对方对自己的FIN的ACK,就可以双双进入TIME_WAIT状态。CLOSING状态比较特殊,实际情况中应该是很少见,属于一种比较罕见的例外状态。正常情况下,当你发送FIN报文后,按理来说是应该先收到(或同时收到)对方的ACK报文,再收到对方的FIN报文。但是CLOSING状态表示你发送FIN报文后,并没有收到对方的ACK报文,反而却也收到了对方的FIN报文。什么情况下会出现此种情况呢?其实细想一下,也不难得出结论:那就是如果双方几乎在同时close一个SOCKET的话,那么就出现了双方同时发送FIN报文的情况,也即会出现CLOSING状态,表示双方都正在关闭SOCKET连接。

1. 为什么建立连接协议是三次握手,而关闭连接却是四次握手呢?

  这是因为服务端的LISTEN状态下的SOCKET当收到SYN报文的建连请求后,它可以把ACK和SYN(ACK起应答作用,而SYN起同步作用)放在一个报文里来发送。但关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你可能未必会马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。

三次握手:为了保证服务端能收接受到客户端的信息并能做出正确的应答而进行前两次(第一次和第二次)握手,为了保证客户端能够接收到服务端的信息并能做出正确的应答而进行后两次(第二次和第三次)握手。

2. 为什么主动关闭方接收到FIN包后等待2MSL呢?

MSL即Maximum Segment Lifetime,也就是报文最大生存时间,引用《TCP/IP详解》中的话:“它(MSL)是任何报文段被丢弃前在网络内的最长时间。”

第一,虽然双方都同意关闭连接了,而且握手的4个报文也都协调和发送完毕,按理可以直接回到CLOSED状态(就好比从SYN_SEND状态到ESTABLISH状态那样);但是因为我们必须要假想网络是不可靠的,你无法保证你最后发送的ACK报文会一定被对方收到,因此对方处于LAST_ACK状态下的SOCKET可能会因为超时未收到ACK报文,而重发FIN报文,所以这个TIME_WAIT状态的作用就是用来重发可能丢失的ACK报文。

第二,报文可能会被混淆,意思是说,其他时候的连接可能会被当作本次的连接。

注:setsockopt中的SO_REUSEADDR是让端口释放后立即就可以被再次使用

不一定要四次挥手:可以通过设置SOCKET变量的SO_LINGER标志来避免SOCKET在close()之后进入TIME_WAIT状态,这时将通过发送RST强制终止TCP连接(取代正常的TCP四次握手的终止方式)。但这并不是一个很好的主意,TIME_WAIT 对于我们来说往往是有利的。

3. 在TCP建立连接的三次握手阶段,如果客户端发送的第三个ACK包丢了,那么客户端和服务器端分别进行什么处理?

当Client端收到Server的SYN+ACK应答后,其状态变为ESTABLISHED,并发送ACK包给Server;如果此时ACK在网络中丢失,那么Server端该TCP连接的状态为SYN_RECV,并且依次等待3秒、6秒、12秒后重新发送SYN+ACK包(指数退避),以便Client重新发送ACK包。Server重发SYN+ACK包的次数,可以通过设置/proc/sys/net/ipv4/tcp_synack_retries修改,默认值为5。 如果重发指定次数后,仍然未收到ACK应答,那么一段时间后,Server自动关闭这个连接。但是Client认为这个连接已经建立,如果Client端向Server写数据,Server端将以RST包响应,方能感知到Server的错误。
 

3.状态转移

4.流量控制——滑动窗口

4.1 利用滑动窗口可以提高传输速度

我们知道,TCP是以报文段为单位发送数据的,如果每发一个段就进行一次确认应答处理的话,这样的传输方式有一个缺点。那就是,包的往返时间越长通信性能就越低。为了解决这个问题,TCP引入了窗口这个概念。即使在往返时间较长的情况下,它也能控制TCP网络通信性能的下降。

具体是怎么做的呢?

为了便于说明滑动窗口机制的工作原理,我们假定数据传输只在一个方向上进行,A(发送方) —> B(接收方),即 A 发送数据,B 接收数据并给出确认。

发送方发送数据时不再是一次只发送一个TCP报文段,而是一次连续发送多个报文段。也就是说,发送方在发送了一个段之后不必一直等待这个段的确认应答,而是继续发送下一个报文段。每当收到一个报文段的确认应答后,窗口就向前滑动一个报文段的长度,因为已发送并收到确认应答的报文段不需要再保留在窗口中了,但已发送还未收到确认应答的段还必须保留在窗口中,以便在超时重传时使用。需要注意的是,滑动窗口是以字节为单位向前滑动的。

示例:假设一个TCP报文段包含有1000字节的数据(注意:不包含TCP首部长度),发送端一次发送4个报文段。如下图所示:

 说明:滑动窗口的大小是4个报文段的数据部分长度,即4000字节。这里的窗口大小就是指无需等待确认应答而可以继续发送数据的最大值。

当主机A收到第1个报文段的确认应答后(收到主机B发来的确认号1001),即序号 1 ~ 1000 的数据已被确认,此时滑动窗口就可以向前移动1000字节的长度,此时窗口的左边界序号是1001,右边界序号是5001。右边界 - 左边界 = 窗口大小。

当主机A收到第2个报文段的确认应答后(收到主机B发来的确认号2001),即序号 1001 ~ 2000 的数据已被确认,此时滑动窗口继续向前移动1000字节的长度,此时窗口的左边界序号是2001,右边界序号是6001。

 分析:窗口以外的部分中,窗口左边部分表示已发送且已收到确认应答。这些数据显然不需要再保留了。窗口右边部分表示不允许发送的数据。因为接收方都没有为这部分数据保留临时存放的缓存空间。

 可以发现,发送窗口的位置由窗口左边界和右边界共同确定。发送窗口左边界每次都是滑动到收到确认应答号的位置上,而发送窗口右边界则是不允许发送数据的第1个字节序号。

这种可以顺序地将多个报文段同时发送以提高TCP通信性能的机制,被称为滑动窗口机制。

4.2 发送窗口与接收窗口

上面所讲的内容是从发送方的角度来解释滑动窗口机制的。发送方的窗口称为发送窗口,而接收方也有一个窗口,称为接收窗口。

发送窗口,表示的是发送方一次可以连续发送出去的数据量,以字节为单位。凡是已经发送过的数据,在未收到确认之前都必须暂时保留在发送窗口中,以便在超时重传时使用。发送窗口内的数据都是尚未收到确认应答的。

接收窗口,表示的是接收方一次能够连续接收的数据量,以字节为单位。接收窗口内的数据都是允许被接收的。

需要注意的是,发送窗口值不是由发送方自己决定的,而是根据接收方给出的窗口值,发送方再构造出自己的发送窗口值。

在TCP报文段的首部结构中,有一个“窗口”字段,其作用是告诉对方本端的接收窗口的大小,以便控制发送方的发送窗口大小。

二者的关系:发送窗口值 ≤ 接收窗口值

此外,发送方的发送窗口大小还要受到当前网络拥塞程度的制约。我们暂时不考虑网络拥塞的影响,后续讲述TCP拥塞控制时再讨论。

为了便于下面的解释说明,我们假定一个TCP报文段的数据部分长度为1字节,数据传输方向为:A(发送方) —> B(接收方)

假定发送方A的发送窗口大小为20字节,接收方B的接收窗口也为20字节。

现在假定A发送了序号为 31~41 的数据。这时,发送窗口位置并未改变,但发送窗口内靠后面的有11字节(黑色小方框表示)表示已发送但未收到确认。而发送窗口内靠前面的9个字节(42~50)是允许发送但尚未发送的。如下图所示:

从上图可以看出,要描述一个发送窗口的状态需要三个指针:P1,P2 和 P3。指针都指向字节的序号。这三个指针指向的几个部分的意义如下:

  • P3 - P1 = A的发送窗口
  • P2 - P1 = 已发送但尚未收到确认的字节数
  • P3 - P2 = 允许发送但目前尚未发送的字节数(又称为可用窗口或有效窗口)

同时,可以看到,发送方的包可以分为四种状态:

已发送并收到确认的包
已发送但尚未收到确认的包
允许发送但尚未发送的包
不允许被发送的包
<说明> 这里的包指的是TCP报文段,因为TCP是以报文段为单位发送数据的。

        再来看看接收方B的接收窗口。B 的接收窗口大小为20字节。在接收窗口以外的部分,到序号30为止的数据都是已经发送过确认,并且已经交付上层应用了。因此在 B 的接收窗口中可以不用再保留这些数据。接收窗口内的数据(31~50)是允许接收的。在上图中,B 收到了序号为 32 和 33 的数据。这些数据没有按序到达,因为序号为 31 的数据没有收到(也许丢失了,也许滞留在网络中的某处)。请注意,接收方 B 只能对按序收到的数据中的最高序号给出确认应答,因此 B 发送的确认报文段中的确认号仍为 31(即期望下一次收到的序号),而不能是 32 或是 33,更不能是34。

        现在假定 B 收到了序号为31的数据,并把序号为 31~33的数据交付主机,然后B从接收缓存中删除这些数据。接着把接收窗口向前移动3个序号的长度,同时给A发送确认,其中B的接收窗口值仍为20,但确认号为34。这表明 B 已经收到了序号 33 为止的数据。我们注意到,B 还收到了序号为37,38 和 40 的数据,但这些都没有按序到达,只能先暂存在接收窗口中。A收到B的确认后,就可以把发送窗口向前滑动3个序号的长度,但指针P2不动。可以看出,现在A的可用窗口增大了,可发送的序号范围是 42~53,即12个序号的长度,之前是9个序号的长度。

如下图所示:


A收到新的确认号,发送窗口向前移动
         A 在继续发送 42 ~ 53 的数据后,指针P2向前移动和指针P3重合,意味着此时可用窗口大小为0。发送窗口内的序号都已用完,但还没有收到确认(如下图所示)。由于A的发送窗口已满,可用窗口已减小到零,因此必须停止发送数据。请注意,存在下面这种可能性:

发送窗口内所有的数据都已正确达到B,B 也早已发出了确认。但不幸的是,所有这些确认都滞留在网络中了。在没有收到B的确认时,A 不能猜测:“获取 B 收到了吧”。为了保证可靠传输,A 只能认为 B 还没有收到这些数据。于是,A 在经过一段时间后(由超时计时器控制)就重传发送窗口中的这部分数据(34 ~ 53),重新设置超时计时器,直到收到B的确认为止。如果 A 收到的确认号落在了发送窗口内,那么A就可以使发送窗口继续向前滑动,并发送新的数据。此时,指针P1指向的位置就是A收到的确认号的位置。


发送窗口内的序号都属于已发送但未被确认


滑动窗口总结

1、TCP首部中的窗口字段指出了现在运行对方发送的数据量。窗口值是经常动态变化者的。

2、TCP 使用滑动窗口机制。发送窗口里面的序号表示允许发送的序号。发送窗口左边的部分表示已发送且已收到了确认应答,而发送窗口右边的部分表示不允许发送。发送窗口右边界的变化有两种情况:一是不动(没有收到新的确认应答);二是前移(收到了新的确认应答)。发送窗口通常是不断向前移动的。

4.3 发送缓存与接收缓存,以及窗口与缓存的关系

缓存也就是缓冲区。

发送缓存:发送方的缓冲区用于存储已经准备就绪的数据和已经发送但尚未收到确认的数据。

接收缓存:接收方缓冲区用于存储已经被接收但是还没有被用户进程消费的数据和未按序到达的数据(这部分数据不能被用户进程消费)。

发送方的应用进程把字节流数据写入 TCP 的发送缓存,而接收方的应用进程则从 TCP 的接收缓存中读取字节流数据。

下图是缓存和窗口的关系:

图中画出了发送方维持的发送缓存和发送窗口,以及接收方维持的接收缓存和接收窗口。


TCP 的缓存和窗口的关系

1、发送方的情况

由上图 (a) 可以看到,发送缓存用来暂时存放:

(1)发送应用程序传送给发送方TCP准备发送的数据。

(2)TCP已发送但尚未收到确认的数据(图中黑色部分)。

        发送窗口通常只是发送缓存的一部分。已被确认的数据应当从发送缓存中删除,因此发送缓冲和发送窗口的左边界是重合的。发送应用程序最后写入发送缓存的字节序号减去最后被确认的字节序号,就是还保留在发送缓冲中的被写入的字节数。发送应用程序必须控制写入发送缓冲的速率,不能太快,否则发送缓存就没有存放数据的空间了。

2、接收方的情况

由上图 (b) 可以看到,接收缓存用来暂时存放:

(1)按序达到的、但尚未被接收应用程序读取的数据。

(2)未按序到达的数据。

        接收窗口通常也是接收缓存的一部分。如果收到的报文段被检测出有差错,则要丢弃。如果接收应用程序来不及读取收到的数据,接收缓存最终会被填满,使接收窗口减小到零。反之,如果接收应用程序能够及时从接收缓存中读取收到的数据,接收窗口就可以增大,但最大不能超过接收缓存的大小。图 (b) 中还指出了下一个期望收到的字节序号。这个字节序号也就是接收方回复给发送方的确认报文段的首部中的确认号。

根据以上的讨论,我们还需要强调以下三点:

第一,虽然发送方的发送窗口是根据接收方的接收窗口设置的,但在同一时刻,发送方的发送窗口并不总是和 接收方的接收窗口一样大。这是因为通过网络传送窗口值需要经历一定的时间滞后(这个时间是不确定的)。另外,发送方还可能根据当前网络的拥塞情况适当减小自己的发送窗口数值。本文前面已经对此说明了发送窗口和接收窗口值之间的关系。

第二,对于不按序到达的数据应如何处理,TCP标准并无明确规定。如果接收方把不按序到达的数据一律丢弃,那么接收窗口的管理将会比较简单,但这样做对网络资源的利用不利(因为发送方会重复传送较多的数据)。因此 TCP 通常对不按序到达的数据是先临时存放在接收窗口中,等到字节流中所缺少的字节收到后,再按序交付上层的应用进程。

第三,TCP 要求接收方必须有累计确认的功能,这样可以减少传输开销,同时也能提高传输效率。接收方可以在合适的时候发送确认,也可以在自己有数据要发送时把确认信息顺便捎带上。但请注意两点:一是接收方不应过分推迟发送确认,否则就会导致发送方不必要的重传,这反而浪费了网络的资源。TCP标准规定,确认推迟的时间不应超过 0.5 秒。若收到一连串具有最大长度的报文段(即报文段长度为MSS),则必须每隔一个报文段就发送一个确认 [RFC 1122]。二是捎带确认实际上并不经常发生,因为大多数应用程序很少同时在两个方向上发送数据。

最后再强调一下,TCP 的通信是全双工通信。通信中的每一方都在发送和接收报文段。因此,每一方都有自己的发送窗口和结束窗口。在谈到这些窗口时,一定要弄清楚是哪一方的窗口。
TCP协议-TCP的流量控制_tcp流量控制-CSDN博客

5.拥塞控制

在某段时间,若对网络资源的需求超过了该资源所能提供的可用部分,网络的性能就要变化,这种情况叫做拥塞

在TCP的窗口控制下,发送端一次发送的数据量为窗口大小,在网络状态不好的情况下,一下子发送过多的数据,可能会导致网络瘫痪。 为了应对这种情况,TCP需要对发送端发送到网络中的数据量进行控制。


拥塞控制 和 流(量)控制的差别:

     所谓拥塞控制就是防止过多的数据注入到网络中,这样可以使网络中的路由器或链路不致过载。拥塞控制所要做的都有一个前提,就是网络能承受现有的网络负荷。拥塞问题是一个全局性的问题,涉及到所有的主机、所有的路由器、以及与降低网络传输性能有关的所有因素。

流量控制往往指的是点对点通信量的控制,是个端到端的问题。流量控制所要做的就是控制发送端发送数据的速率,以便使接收端来得及接受。前面已经整理过。


拥塞控制方法

因特网建议标准RFC2581定义了进行拥塞控制的四种算法,即慢开始(Slow-start)、拥塞避免(Congestion Avoidance)、快重传(Fast Restrangsmit) 和快回复(Fast Recovery)。

 慢开始和拥塞避免

发送方维持一个叫做拥塞窗口cwnd(congestion window)的状态变量。拥塞窗口的大小取决于网络的拥塞程度,并且动态地在变化。发送方让自己的发送窗口等于拥塞窗口,另外考虑到接受方的接收能力(点对点的流量控制),发送窗口可能小于拥塞窗口。  发送方控制拥塞窗口的原则是:只要网络没有出现拥塞,拥塞窗口就增大一些,以便把更多的分组发送出去。但是只要网络出现拥塞,拥塞窗口就减小一些,以减少注入到网络的分组数。

慢开始算法的思路:最初的TCP在连接建立成功后会向网络中发送大量的数据包,这样很容易导致网络中路由器缓存空间耗尽,从而发生拥塞。因此新建立的连接不能够一开始就大量发送数据包,而只能根据网络情况逐步增加每次发送的数据量,以避免上述现象的发生。具体来说,当新建连接时,cwnd初始化为1个最大报文段(MSS)大小(MSS即TCP的每个包的大小),发送端开始按照拥塞窗口大小发送数据,每当有一个报文段(一个数据包)被确认,cwnd就增加至多1个MSS大小。用这样的方法来逐步增大 拥塞窗口CWND。

 这里用报文段的个数(数据包的个数)的拥塞窗口大小举例说明慢开始算法,实时拥塞窗口大小是以字节为单位的。如下图:

上图中的轮次,指的是 一个窗口内的所有数据包被全部回复 称为一轮,所以每轮过后cwnd值翻倍,指数增长。

为了防止cwnd增长过大引起网络拥塞,还需设置一个慢开始门限ssthresh状态变量,避免一直指数增长。ssthresh的用法如下:

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

  当cwnd>ssthresh时,改用拥塞避免算法。

  当cwnd=ssthresh时,慢开始与拥塞避免算法任意。

拥塞避免算法思路:让拥塞窗口缓慢增长,即每经过一个往返时间RTT就把发送方的拥塞窗口cwnd加1,而不是加倍。这样拥塞窗口按线性规律缓慢增长。

       无论是在慢开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞(其根据就是没有收到确认,虽然没有收到确认可能是其他原因的分组丢失,但是因为无法判定,所以都当做拥塞来处理),就把慢开始门限设置为出现拥塞时的发送窗口大小的一半。然后把拥塞窗口设置为1,执行慢开始算法。这样做的目的就是要迅速减少主机发送到网络中的分组数,使得发生拥塞的路由器有足够时间把队列中积压的分组处理完毕。
  如下图:

 

乘法减小和加法增大

  乘法减小:是指不论在慢开始阶段还是拥塞避免阶段,只要出现超时,就把慢开始门限减半,即设置为当前的拥塞窗口的一半(于此同时,执行慢开始算法)。当网络出现频繁拥塞时,ssthresh值就下降的很快,以大大减小注入到网络中的分组数。

  加法增大:是指执行拥塞避免算法后是拥塞窗口缓慢增大,以防止网络过早出现拥塞。

快重传和快恢复

一条TCP连接有时会因收不到对端的ACK, 等待重传计时器的超时而空闲较长的时间,慢开始和拥塞避免无法很好的解决这类问题,因此提出了快重传和快恢复的拥塞控制方法。

快重传算法并非取消了重传机制,只是在某些情况下更早的重传丢失的报文段(如果当发送端接收到三个重复的确认ACK时,则断定分组丢失,立即重传丢失的报文段,而不必等待重传计时器超时)。

快重传要求接收方在收到一个失序的报文段后就立即发出重复确认(为的是使发送方及早知道有报文段没有到达对方)。快重传算法规定,发送方只要一连收到三个重复确认就应当立即重传对方尚未收到的报文段,而不必继续等待设置的重传计时器时间到期。如下图:

快重传配合使用的还有快恢复算法,有以下两个要点:

  ①当发送方连续收到三个重复确认时,就执行“乘法减小”算法,把ssthresh门限减半。但是接下去并不执行慢开始算法。

  ②考虑到如果网络出现拥塞的话就不会收到好几个重复的确认,所以发送方现在认为网络可能没有出现拥塞。所以此时不执行慢开始算法,而是将cwnd设置为ssthresh减半后的大小,然后执行拥塞避免算法。如下图:

在采用快恢复算法时,慢开始算法只是在TCP连接建立时和网络出现超时时才使用。


cwnd (Congestion Window): cwnd 即拥塞窗口(Congestion Window),是TCP为了防止网络拥塞而限制发送方数据发送速率的一个动态调整的窗口大小。在连接建立之初,cwnd通常初始化为一个较小的值,例如1个或几个最大段大小(MSS)。在慢启动阶段,cwnd按照指数增长,每收到一个ACK确认就翻倍,直到达到ssthresh值。进入拥塞避免阶段后,cwnd的增长变为线性,每次确认仅增加一个MSS。如果检测到丢包,TCP会减少cwnd的大小并可能重新进入慢启动阶段,以此来响应网络拥塞。

ssthresh (Slow Start Threshold): ssthresh 代表慢启动阈值(Slow Start Threshold)。这是TCP拥塞控制算法中的一个关键变量,用于区分慢启动阶段和拥塞避免阶段。当TCP连接开始或者发生拥塞导致数据包丢失时,ssthresh的值会被调整。初始情况下,ssthresh通常设置为一个较大的值,比如接收窗口大小或65535字节。在网络出现拥塞迹象(如超时或收到三个重复的ACK确认)后,ssthresh的值常常会被更新为当前拥塞窗口(cwnd)的一半,从而减缓数据的发送速率,进入拥塞避免阶段。

这两个参数共同作用,帮助TCP连接在保证数据传输效率的同时,尽量避免或减轻网络拥塞。通过动态调整cwnd和ssthresh,TCP能够适应网络条件的变化,优化数据传输性能。


参考:

https://www.cnblogs.com/wxgblogs/p/5616829.html

  • 8
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
TCPUDP是两种常用的传输层协议,它们在很多方面有所不同。首先,TCP面向连接的协议,而UDP面向连接的协议。这意味着TCP在通信之前需要建立连接,而UDP则不需要。\[2\] 其次,TCP保证数据的正确性,通过使用序列号、确认号和校验和等机制来确保数据的可靠传输。而UDP则不提供数据的可靠性保证,它只是简单地将数据包发送出去,不关心是否到达目的地。因此,UDP可能会丢包。\[2\] 另外,TCP传输速度相对较慢,因为它需要进行连接的建立和断开,并且还需要保证数据的可靠性和有序性。而UDP传输速度较快,因为它没有这些额外的开销。\[2\] 此外,TCP是一对一的连接,即一台主机与另一台主机之间建立一条连接。而UDP可以支持一对多、多对多和多对一的交互。\[2\] 对于发送即时消息,一般会选择使用TCP协议。因为TCP可以保证数据的可靠性,确保消息能够准确地传输到目的地。而UDP则不适合发送即时消息,因为它无法保证消息的可靠性和有序性。\[1\] 总结来说,TCPUDP在传输速度、数据可靠性、连接方式和适用场景等方面有所不同。具体选择哪种协议取决于具体的需求和应用场景。\[2\] #### 引用[.reference_title] - *1* *2* [网络面试题:TCPUDP区别及三次握手,四次挥手](https://blog.csdn.net/weixin_44844089/article/details/115469779)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [面试TCPUDP两者的区别是什么?](https://blog.csdn.net/weixin_45629285/article/details/121077455)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JAVA技术开发员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值