Linux网络 - 再谈、详谈UDP和TCP协议

news2024/12/27 0:05:33

文章目录

  • 前言
  • 预备
    • netstat
    • pidof
    • cat /etc/services
  • 一、UDP协议
    • UDP协议端格式
    • UDP的缓冲区
    • 基于UDP的应用层协议
  • 二、TCP协议
    • 1.TCP协议段格式
    • 确认应答(ACK)机制
      • 三次握手
        • 疑问1 最后一次客户端发给服务端的ACK请求怎么保证服务端能够收到?
      • 四次挥手
        • 疑问2 为什么挥手是四次,握手只有三次?
    • 4位首部长度
    • 32位序号
    • 32位确认序号
    • 16位窗口大小
    • 16位紧急指针
      • 什么场景才会用到发送紧急数据
    • 六个标记位
    • 超时重传机制
      • 重复报文如何处理
      • 超时重传,那我们要超时多久才重传呢?
    • 连接管理机制
      • 三次握手状态
        • ESTABLISHED
        • 模拟三次握手状态变化
        • 全连接队列
        • 半连接队列
      • 四次挥手状态
        • TIME_WAIT等待多长时间呢?
          • 什么是MSL?
        • 模拟四次挥手环境
            • setsockopt
    • 流量控制
    • 滑动窗口
    • 延迟应答
    • 阻塞控制


前言

上一章我们已经学习了HTTPS协议,知道了HTTPS协议的基本原理。
本章我们将回过头来重新深度讲解UDP协议和TCP协议,


预备

这里再介绍一下之前用过的工具

netstat

netstat是一个用来查看网络状态的重要工具。

  • -n 拒绝显示别名,能显示数字的全部转化成数字
  • -l 仅列出有在 Listen (监听) 的服務状态
  • -p 显示建立相关链接的程序名
  • -t (tcp)仅显示tcp相关选项
  • -u (udp)仅显示udp相关选项
  • -a (all)显示所有选项,默认不显示LISTEN相关

pidof

之前我们想查看一个进程的pid,然后kill杀死它,我们一直都是使用的ps axj来查看的,pidof [进程名] 可以直接查看进程的pid。

在这里插入图片描述

cat /etc/services

可以查看服务器绑定的特殊知名端口号

比如
mysql服务器,使用3306端口
ssh服务器, 使用22端口
ftp服务器, 使用21端口
telnet服务器, 使用23端口
http服务器, 使用80端口
https服务器, 使用443端口

一、UDP协议

我们本次重谈UDP协议通过UDP报头的分析和UDP的发送缓冲区来讲解。

UDP协议端格式

在这里插入图片描述
首先对于16位的源端口号和16位的目的端口号,很好理解,这里就不再重复。

16位UDP长度是什么? 代表的是下面携带的数据的字节长度,通过16位的UDP长度,我们就可以分析出一个UDP报文可以携带的数据最多为2^16 - 1= 65535字节,64kb的数据。

16位UDP检验和我们这里不讲。

UDP的缓冲区

UDP只有接收缓冲区,没有发送缓冲区。
这是因为UDP协议属于不可靠、无连接协议。

不可靠代表UDP只需要向目标主机发数据即可,不考虑数据丢失等其他问题,也就不需要像TCP协议一样如果数据发送失败或者数据丢失、乱序,需要重传数据,也就不需要发送缓冲区

无连接代表使用UDP协议的主机不需要与目标主机建立连接。

因为没有发送缓冲区,所以我们调用sendto就是直接将数据从应用层直接交给OS的传输层,再向下交给网络层。

UDP具有接收缓冲区,是因为我们可能会同时收到一连串的报文,而应用层未必能来得及全部读完,所以就需要有接收缓冲区。
不过需要注意的是,如果接收缓冲区满了,之后再接收的报文会被丢失。

基于UDP的应用层协议

NFS: 网络文件系统
TFTP: 简单文件传输协议
DHCP: 动态主机配置协议
BOOTP: 启动协议(用于无盘设备启动)
DNS: 域名解析协议

二、TCP协议

本章主要重点是放在TCP协议上,首先我们需要再重新重视一下TCP的英文全称(Transmission Control Protocol)传输控制协议,那么它这里的"控制"是如何体现的?

我们也从TCP的报头来分析

1.TCP协议段格式

在这里插入图片描述

16位的源端口号和16位目的端口号我们这里也不再重复了。
由于TCP协议的报头格式比较复杂,所以我们拆开来讲

确认应答(ACK)机制

Tcp为确保可靠性,要尽可能的保证我发出去的报文是已经被对方收到的,如果没有被对方收到,就需要补发重传。 那么发数据的一方是怎么知道对方是否收到呢? 需要对方来告知,也就是确认应答。、

三次握手

在这里插入图片描述
SYN就是发送连接请求,我们等会还会再讲SYN。
ACK这里就是确认应答。

所以看上图的三次发送数据,也就是三次挥手。

第一次是客户端发给服务端SYN连接请求。

第二次是服务端给客户端发送第一次SYN的ACK确认应答,同时也向客户端也发送SYN连接请求。

第三次是客户端给服务端发送ACK确认应答。

这就是三次握手,同时我们可以发现客户端和服务端都通过至少发送和接受一次数据来验证了自身socket的全双工是否工作正常。

三次握手是Tcp协议中十分重要的一环,等会我们还会讲到。

疑问1 最后一次客户端发给服务端的ACK请求怎么保证服务端能够收到?

不能保证,不过大家可以想一想,就算服务端也再发一次ACK请求给客户端,那客户端要不要响应呢? 如果又发送响应是不是就一直这么循环下去了? 所以干脆我们就只需要三次握手就行了。

四次挥手

在这里插入图片描述
这里的四次挥手,与上面的三次握手也有异曲同工之妙。
第一次挥手是 客户端向服务器发送的FIN断开连接请求,就是告诉服务器我没有数据向你再发了,我想断开连接。

第二次挥手是 服务器对于客户端的断开连接请求发出ACK应答,证明我收到了你了连接请求了,但是不代表我同意关闭。 因为你客户端没数据发了,不代表我服务端没有数据再发了,所以中间服务端可以再向客户端发消息,而这个时候客户端也是能接受的,因为四次挥手还没有完成,不会断开连接。

第三次挥手是 当服务端也没有数据可以再发了,而且自身也处于CLOSE_WAIT状态,它也会向客户端发送FIN断开连接请求。

第四次挥手是 客户端对服务端的FIN断开连接请求发送ACK确认应答。当服务器收到了ACK之后,立马就将建立的连接断开并把资源释放了。

四次挥手是Tcp协议中十分重要的一环,等会我们还会讲到。

疑问2 为什么挥手是四次,握手只有三次?

因为我们可以看到握手的第二次,服务端在发送SYN请求的同时,还做了捎带应答ACK,所以才能压缩成三次。

那为什么我的挥手不能压缩成三次呢?
这是因为服务端在收到客户端的FIN断开连接请求之后,我的服务器可能还会有数据要继续发送,但是又要给客户端作应答表示我收到了你的FIN断开连接请求,所以也就不能作握手一样的捎带应答,所以也就必须要四次挥手。

4位首部长度

在这里插入图片描述
4位首部长度代表的就是TCP协议的报头长度,也就是整个报文除了正文数据的长度。

那么4位可以代表多少字节呢? 2 ^ 4 - 1 = 15,可是我们光16位源端口号到16位紧急指针都已经共有20字节了,这还不包括选项的长度。 所以这里的15的单位不是1字节,而是4字节。 这样通过4位首部长度我们就可以代表15 * 4 = 60字节了,而选项我们通过计算可以知道 ,选项最多可以有40个字节。

32位序号

讲32位序号之前,我们先来了解一些前备知识,当我们建立好连接之后,我们是可以同时连续发送多次请求给服务器的,而当报文数据在传输的时候,能不能保证我们传送过去的报文数据会被按序被目标主机接收?
答案是不能的,因为可能会存在不同报文不通过同一个网络传输过去的情况,而有些网络传输可能会比较缓慢。

那么如果目标主机接收到了这些没有按指定顺序到达的报文,并直接对报文做解析,势必会出现问题,TCP对于可靠协议是不能容忍这种问题的出现,所以也就需要保证报文能够按序被目标主机解析。 虽然不能控制报文到达的顺序,但是我们可以在报头中添加关于顺序的说明,这个顺序的说明,就是我们现在要讲的32位序号。

在这里插入图片描述
只需要对比我们的24位确认序号,我们就可以知道这一连串报文数据的顺序,服务端也就能按序解包报文。

需要注意的是,实际两个主机在进行通信时,我们最初通信时的起始序号可能并不是从1开始的,而是一个随机值,这个随机值是服务端和客户端在开始建立通信,也就是在三次握手的时候就开始协商好的,至于这是为什么?我们后面再讲。

32位序号等会我们还会详细再次讲解。

32位确认序号

既然Tcp要保证可靠性有了确认应答机制,那么我们就需要在确认应答中携带32位确认序号来保证我们已经读取了多少字节的数据。

在这里插入图片描述
当我们收到序号为1000的报文请求时,我们要做出ACK应答,应答就需要带上确认序号,确认序号是你的序号+1。 比如说我发了1000字节的数据给服务端,确认序号是1000,服务端就需要在它的应答报文里的确认序号里填上1001,代表1001之前的数据我读取到了。

通过这样的方式,我们就可以保证客户端知道我们的服务端已经读了多少字节的数据。

如果说我分四次发报文数据一共发了4000个字节,服务端只收到了其中3个或两个,那么服务端就必不可给我发一个确认序号为4001的响应报文,当客户端发现服务端没有完全读完,然后根据响应报文中的确认序号,知道对方收到了多少字节数据,就知道我需要重发,从多少开始重发。

32位确认序号等会还会再相信讲解。

16位窗口大小

窗口大小指的是无需等待确认应答而可以继续发送数据的最大值。

当我们的服务端压力比较大的情况下,接收缓冲区的内容没办法短时间内快速取出,而客户端又在不断向服务端发送报文数据的时候,接收缓冲区的剩余空间就在不断缩小。

这个时候就需要告知客户端,服务端的接收缓冲区快顶不住了,让客户端发慢一点或者别发了,再发接受缓冲区满了,满了的话再发的报文就会被丢弃。 所以也就需要16位窗口大小来告诉客户端服务端的接收缓冲区剩余大小,也可以理解为可以继续发送数据的最大值。

16位窗口等会我们还会详细讲解。

16位紧急指针

这个我们基本很少会用到,只有在传送紧急数据的时候,16位紧急指针才会被设置,并且还有URG标记位也会被设置,当URG被置1时,说明有紧急数据。
在这里插入图片描述

16位紧急指针是报文正文的偏移量,且紧急数据最多只能有1个字节。
我们可以通过在send的flags参数设置MSG_OOB来携带带外数据(也就是紧急数据)
在这里插入图片描述

什么场景才会用到发送紧急数据

一般我们很少几乎用不到发送紧急数据,很少的应用程序会用到这个。

但是有一种场景我们可以了解一下,就是当客户端向服务端发送一个报文,确始终得不到应答,但是我又能确认连接是没问题的,我的消息发送是没问题的。 我就需要知道服务器那边是处于一种什么情况,为什么对我的报文不做回应,这个时候就可以穿一个紧急数据过去,然后服务端也专门用一个线程用来接收紧急数据,然后再应答回去告诉客户端服务端可能处于一种什么状态,没办法及时处理你的报文。

六个标记位

在这里插入图片描述
URG:标记紧急指针是否有效,是否携带紧急数据。
ACK:只要有确认应答属性,就必须要带上ACK标记位!确认序号是否有效。
PSH:提示接收端应用程序立刻从TCP缓冲区把数据读走,
RST: 对方要求重新建立连接; 我们把携带RST标识的称为复位报文段。
SYN: 请求建立连接; 我们把携带SYN标识的称为同步报文段。
FIN: 通知对方, 本端要关闭了。

超时重传机制

为了确保数据会被对方接收,我们已经知道了有确认应答机制,只有接收数据一方收到数据后发出ACK确认应答,并且这个应答被发数据的一方也接收到了,至此,才完成一次数据的通信。

那么如果数据在中途丢包了呢? 或者应答在网络传输过程中也丢包了呢? 又或者我们的数据被由于网络状况不好,阻塞在网络中了呢?
在这里插入图片描述
以上图为例,只要我们的主机A没有收到确认应答(确认应答是携带确认序号的),就无法确定主机B是否真的收到了数据,那么我们就要在特定的时间间隔进行数据重传。

所以不管是上面提出的哪三种情况,我们的超时重传机制都能够处理这些情况,其中如果是网络状态不好,造成主机A发出的数据阻塞在网络中,主机A也需要进行超时重传,如果这个时候第一次发出的数据由于网络又通畅了,被主机B接收到了,两次发出的数据就都有可能会被主机B收到,那么对于主机B就收到了重复的报文数据,对于重复的报文数据我们应该如何处理呢?

重复报文如何处理

因为我们的报文数据是携带了序号的,所以完全不用担心收到重复报文,只需要对比序号,将多余的重复报文直接丢弃即可。

超时重传,那我们要超时多久才重传呢?

超时重传的这个时间间隔是比较难以界定的,如果设置的时间间隔太短,可能由于网络本身传输就需要一定时间,就会导致时间间隔内一直都收不到应答,并不断重发重复的报文数据。 那如果设置的时间间隔太长,又会影响整体的重传效率,

所以,针对这一问题,Tcp采用的是一种动态的时间间隔。
这个时间间隔一500ms为单位,之后判定重发的时间间隔都是这个单位的整数倍。
比如第一次超时重传的时间间隔为500ms,500ms内没有收到应答之后,就重传一次。然后第二次的时间间隔就变为了500 * 2 = 1000ms,而如还是没有收到应答,就再重传一次,以此类推。 等累计到了一定次数,Tcp就会认为网络或者对方出现问题,强制关闭连接。

连接管理机制

在这里插入图片描述
这里的连接管理机制,我们主要详谈客户端与服务器在三次握手、四次挥手过程中的状态变化。


三次握手状态

当客户端第一次发送SYN请求的时候,自身tcp连接处于SYN_SENT状态。
当服务端收到SYN请求后,向对方发送应答和SYN请求时,将自身置为SYN_RCVD状态。
当客户端接收到服务端的SYN请求和应答时,给服务端发送ACK应答的同时,将自身tcp连接置为ESTABLISHED,ESTABLISHED代表自身连接已经建立好了。

ESTABLISHED

只有tcp连接处于ESTABLISED才认为是建立好了连接!

所以,对于第一次发送握手请求的主机来说,当我发出应答时,tcp就默认建立好了连接。
对于另一台主机而言,只有我收到了应答,才能算式建立好了连接。

那么为什么这样设计有什么好处呢?

如果我们的请求连接的过程造成了请求报文或应答丢包的情况,前两次握手都还好,因为我们双方都没有建立好连接,都是处于请求连接的状态。 那么如果第三次握手的应答丢失了,就会造成了发送第一次握手请求的主机已经建立好了连接,但是由于应答丢失,另一台主机收到确认应答也就没有真正建立好连接。 这样就会造成发送第一次握手请求的主机单方面以为自己建立好了连接。而为了维护这个连接,OS就需要耗费资源去维护,也就浪费了系统资源。

一般实际情况其实都是客户端向服务端发起连接,所以这种机制就将上面会发生的情况的后果成本转移到了客户端身上,而不是服务端。毕竟服务端是要为许多客户端服务的,本身就需要可能维护大量的tcp连接,OS资源的浪费就有可能导致服务器挂掉。

如果发生上述情况,我们可以再进一步向下推演,客户端单方面以为双方都建立好了连接,于是开始传数据,但是我们的服务端还正处于SYN_RECV状态,突然收到了一段不是应答的数据,服务端就大概知道什么情况了,于是就发送一段将RST标记位为1的报文报头数据,要求客户端重新建立连接。


现在再回过头来看三次握手的这些状态。

我们能否看到这三次握手的状态的变化呢?

模拟三次握手状态变化

通过我们之前写的TcpServer代码,我们进行一些改动
在这里插入图片描述
为什么这里要特意不进行accept呢? accept函数其实并不参与连接过程,Accept的作用主要在于将内核传输层中建立好的连接拿到应用层。 不进行accept可以更好的让我们看到模拟实验现象。

在这里插入图片描述
将backlog设置为1,backlog是我们listen的参数,之前我们一直不理解这个参数是什么意思,等会我们就知道了。

我们提前准备好3个客户端窗口,1个服务端窗口,2个检测tcp连接的窗口。

现在现将服务端运行起来,并让两个客户端连接服务端,我们就会看到这样的一个现象。
在这里插入图片描述
而现在,我们开始让第三个客户端连服务端,会发生什么?

在这里插入图片描述
这里我们第三个客户端的连接在服务端是处于SYN_RECV状态。 可是为什么呢?

导致的原因有两个,一个原因是我们没有进行accept,我们的backlog被设置为了1。

全连接队列

当我们的客户端和服务端进行好了三次握手之后,我们成立建立了连接,也就是处于了ESTABLISHED状态的tcp连接,就需要进行管理起来,而OS就是通过全连接队列来进行管理的,它会将三次握手成功的tcp连接都放入这个队列,等待我们的accept将它们拿到应用层。

所以这我们特意让服务端不调用accept,也就是把那些已经建立好连接的tcp连接一直留在了全连接队列当中。

那为什么第三个连接是处于SYN_RECV状态呢?
先再来看看三次握手的这些状态。
在这里插入图片描述

SYN_RECV也就是处于收到了客户端第一次发来的SYN请求并给客户端发ACK+SYN的时间段。

那当客户端再发ACK应答时,我们这里的tcp连接为什么还没处于ESTABLISHED状态呢?

这是因为我们的全连接队列满了!
至于为什么会满,是因为我们的backlog被我们设置为了1。
全连接队列的长度等于logback+1!

半连接队列

对于已经建立好连接的tcp连接,我们需要进行管理,对于那些还正在进行三次握手的tcp连接,我们也需要进行管理,我们会将这些连接放置在半连接队列中!

而当我们的半连接队列中有连接如果在一定时间内还未收到应答,就会被自动释放。

所以当我们过段时间再调用netstat -ntp查看连接状态时,刚刚处于SYN_RECV的那个连接就消失了。

之前我们说了是因为我们的全连接队列满了所以我们第三个连接才无法进入全连接队列,并不是因为我们没有收到应答,这个应答其实是被tcp协议忽略掉了,因为全连接队列满了!


四次挥手状态

在这里插入图片描述
通过上面的三次握手,四次挥手其实也差不多,不过我们需要注意的是这里的TIME_WAIT状态。

第一次发送FIN请求的主机在收到对方也发来的FIN请求之后,不光也要返回一个ACK应答,同时将自身状态设置为TIME_WAIT状态,并在一段时间之后,将连接关闭。

首先想一想,为什么要等待一点时间再关闭?
因为我们不知道对方主机是否收到了我们的ACK应答,万一它没收到,它就需要补发重传。 如果我在发出应答就直接关闭连接,出现上述情况,我们就没办法收到它补发的FIN请求,就会造成另一个主机迟迟收不到应答,虽然最后的重传机制在重传一定次数后仍会关闭连接,但是这段时间也是耗费OS资源的。所以我们就需要有TIME_WAIT时间。

那么这段等待时间我们是尽量让客户端来维持的, 原因与三次握手一样,服务器的资源要尽可能的利用,尽量少一些浪费资源的行为。

TIME_WAIT等待多长时间呢?

等待时间长度也是有讲究的,我们一般设定时间为 2MSL时间。

什么是MSL?

MSL就是一段TCP报文数据在网络中最大生存时间。
所以,等待2MSL的时间就可以在出现问题的时尽可能的让服务端有时间进行补发重传。
还能让一些中间由于网络堵塞原因的一些报文数据消散,因为我们要考虑到这一种情况,我突然又想再次建立连接,那么这些上次连接的残余报文就有可能会影响我们新的连接,不过这种情况是几乎不可能发生的,因为我们的客户端在连接服务端时采用的是随机端口机制。 并且我们还有24位序号能保证这种情况的发生,也是因为这种原因,我们刚刚上面讲到的,随机序号也是为了避免残余报文影响正常连接。

模拟四次挥手环境

我们一个客户端一个服务端即可,然后一个窗口来观察tcp连接状态。

先启动服务端,然后客户端连接服务端。
此时我们ctrl+c关掉服务端,服务端的tcp就需要向客户端发送FIN断开连接请求,客户端并发送ACK回应,此时我们就可以看到服务端的tcp连接处于FIN_WAIT2状态。
在这里插入图片描述

然后接着我们也关闭掉客户端,就能看到服务端的连接处于 TIME_WAIT状态了。
在这里插入图片描述
等过一点时间再检查连接状态,我们就发现连接消失了。

现在我们再来回过头来想一想之前碰到的问题,我们以前在关闭服务端的时候,然后再重启启动服务端,是不是会碰到
在这里插入图片描述
现在不是就明白了呢?

这是因为我们虽然关闭掉了服务端的进程,但是tcp连接还是处于TIME_WAIT状态,也就是这个端口号正在被使用,自然也就不能重复绑定被使用的端口号。

而我们之前也使用过setsockopt函数能够解决这个情况,可以让刚刚被关闭的服务端,立马重启不用改变端口号,也就是针对这个问题的解决方案,因为对于服务端而言,我虽然出于各种原因挂掉了,但是我需要立马重启服务,否则即使短短几秒没办法重启服务也可能会造成我较大的经济损失。

setsockopt

在这里插入图片描述

int opt = 1;
setsocket(listensocket, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof opt)

流量控制

刚才我们学习32位窗口大小的时候,我们就已经介绍了,双方主机可以通过ACK回应中设置32位窗口大小,就可以让对方主机知道我们的接收缓冲区还剩多少空间,还能接收的最大数据长度。

如果接收方缓冲区满了, 就会将窗口置为0。这时发送方不再发送数据, 但是需要定期发送一个窗口探测数据段, 使接收方把窗口大小告诉发送方。

这种流量控制的好处就在于,可以避免因为接收缓冲区空间不足,而导致接收方不断丢包,发送方不断重传的情况,有效地提高了传输的效率。

滑动窗口

要想理解滑动窗口,我们先来重新再理解一下接收缓冲区。

我们可以将接收缓冲区分为三个部分
在这里插入图片描述

第一个部分是确认应答的数据,已经确认被对方收到的数据我们其实就可以进行覆盖了,不过对于如何覆盖,我们等会再说。

第二个部分是我发送但未应答的数据,这个部分,我们就可以视他为滑动窗口,因为滑动窗口,是受对方缓冲区大小也就是收到的24位窗口大小影响的。

通过这样的一个窗口,我们不仅可以同时维护发送但未应答的数据,区分其他两个部分的数据,也不必再重新开辟一段空间来维护,直接在发送缓冲区放置即可。 这个窗口的区间是通过双指针来划分的。

滑动窗口的大小取决于对方的接收缓冲区的窗口大小,所以我们就可以将滑动窗口内的数据一次性连续发送出去,然后开始等待应答。
滑动窗口大小 = min(对方缓冲区窗口大小,有效数据,阻塞窗口) 这里的阻塞窗口我们等会再谈。

那么它的滑动体现在哪里呢?
这就又要涉及到我们之前说的 序号和确认序号了。
begin = 确认序号。
end = 确认序号 + 窗口大小
当我们将滑动窗口的报文数据连续发送过去之后,我们开始等待应答报文,再通过应答报文中的确认序号和窗口大小,再动态调整滑动窗口的位置和大小。
这就是滑动窗口。

延迟应答

如果接收数据的主机立刻返回ACK应答, 这时候返回的窗口可能比较小。
我们的服务器在一定时间内是会把接收缓冲区内的数据取走一部分的,所以延迟应答,可能就可以让我们返回的窗口大小更大一些。

那么这个延迟多久呢?
对于不同的操作系统有不同的方案,不过大多数都是这两种方案之一。

  • 数量限制: 每隔N个包就应答一次; N一般取2
  • 时间限制: 超过最大延迟时间就应答一次; 时间一般取200ms

阻塞控制

有的时候,我们的网络环境会变得拥堵,发出的数据迟迟阻塞在里面。
所以如果当出现大面积丢包的情况,tcp就需要考虑到有可能是因为网络拥堵阻塞的原因,于是就需要做出相关策略。 我们称这种策略就叫做阻塞控制。

当被tcp判断可能是网络阻塞时,就要开始引入慢启动机制和阻塞窗口(一个阻塞窗口为一个报文数据),所谓的慢启动机制就是第一次一个阻塞窗口的数据,如果能收到应答,下一次就发送2倍的阻塞窗口数据,一次类推,期间如果又发生网络阻塞大面积丢包则再重新轮回一次。

每次发送数据包的时候, 将拥塞窗口和接收端主机反馈的窗口大小做比较, 取较小的值作为实际发送的窗口;
所以我们就能理解上面的 滑动窗口大小 = min(对方缓冲区窗口大小,有效数据,阻塞窗口)。

但是,如果是以2倍的方式增大阻塞窗口,对于这种指数级的增长,后面的增长是十分夸张的,但是指数级增长的前期是相对比较缓慢的,我们对于阻塞的试探只需要慢启动即可,所以我们就需要有一个阈值来限制指数的增长。

当阻塞窗口达到阈值后,就不再以指数进行增长,而是+1。
在这里插入图片描述
这里的乘法减小是对于再次碰到网络阻塞做出的算法调整阈值,将阈值设为碰到拥堵时堵塞窗口/2。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1846457.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

openssl 命令行生成密钥对,生成hash,PSS填充签名,校验

生成密钥对 openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:4096 openssl rsa -pubout -in private_key.pem -out public_key.pem将源文件data.txt生成hash值(sha-256) openssl dgst -sha256 -binary data.txt > d…

利用LabVIEW项目管理和组织LabVIEW应用程序

如何利用LabVIEW项目管理和组织LabVIEW应用程序,提供了关于文件定义、磁盘上的文件组织、LabVIEW项目浏览器、交叉链接和相关资源的建议。这些推荐在开发前就应建立,以确保应用程序能扩展到大量VIs并适应多开发者环境。 目录 定义和识别应用程序文件 磁…

第106天:权限提升-WIN 系统AD域控NetLogonADCSPACKDCCVE 漏洞

目录 案例一:WIN-域控提权-CVE-2014-6324 案例二:WIN-域控提权-CVE-2020-1472 案例三:WIN-域控提权-CVE-2021-42287 案例四:WIN-域控提权-CVE-2022-26923 案例一:WIN-域控提权-CVE-2014-6324 首先先部署域控 项目…

神经阻滞术——慢性腰痛、颈痛与关节痛治疗的新选择

北京精诚博爱医院所实施的神经阻滞术是一种针对患者局部疼痛治疗手段,通过向特定部位注射局麻药或其他特定药物,来暂时性地阻断神经传导,进而达到减轻或消除疼痛的目的。这种疗法在慢性腰痛、颈痛或关节痛等常见疼痛疾病的治疗中,…

案例分享:同为科技与军工项目合作

国防数字化建设发展,同为科技提供智能PDU电源管理器系列产品与服务 项目要求描述: 竖装智能PDU电源管理器 63A输入 2P空气开关 SNMP协议智能型表头 3米310平方阻燃A级线缆 监测总输入电压、总负载电流、总负载视在功率、有功功率、无功功率、总负载…

构建有效的财务规划合作伙伴关系

在这个日益注重分类、定义和正规化的时代,财务规划与分析作为企业环境中发展最快的功能之一,已经从典型的数据管理角色逐步演变成企业框架中必不可少的身份。与其他新兴趋势一样,财务规划也开始采用更加创新的理念来吸引高技能投资&#xff0…

每个程序员都要有 3 份收入!

见字如面,我是军哥! 现在这个就业环境,是真的冷,找工作也确实相比前几年难太多。 程序员人群要想没有收入危机,未来的生活压力,我的建议是一定要提前构建自己的三份收入! 哪三份收入呢&#xff…

帮企商城PC端分销商城企业网站源码系统 带源代码包+搭建部署教程

系统概述 帮企商城 PC 端分销商城企业网站源码系统是一款集企业网站建设、商品管理、分销体系、支付系统等多种功能于一体的综合性平台。它为企业提供了一个全面的电子商务解决方案,帮助企业快速搭建自己的在线商城,并实现高效的运营和管理。 该系统采…

短视频批量下载工具源码逻辑解析(软件)

短视频批量提取第三篇关于视频提取下载的思路 一:概述 因为上一篇不完整,这里其实就是补充第二篇关于源码思路。这里不针对视频评论的提取,只对视频分享链接批量导入下载进行思路解析 二:难点 通常情况下如果直接访问详情页进行…

Hi3861 OpenHarmony嵌入式应用入门--LiteOS Thread

目录 Thread API 主要接口说明 测试代码编写 代码分析 hi3861使用的实时系统主要是基于Huawei LiteOS-M,这是华为针对物联网领域推出的轻量级物联网操作系统内核。LiteOS-M是Huawei LiteOS的一个分支,专为IoT领域构建,主要面向没有MMU&am…

永磁同步电机FOC调试记录(一)

永磁同步电机FOC调试记录(一) 前言架构硬件架构软件架构 调试过程元器件选型开环控制编码器调试速度采样电流检测中断优先级的确定电流环部分烧坏IPM速度-电流环位置-电流环 结语 前言 这是我个人从零开始尝试永磁同步电机(PMSM)…

别只看影响因子了!又1本毕业神刊偷偷被On Hold了!请谨慎投递

【SciencePub学术】昨日,2023JCR正式发布,现在影响因子的话题依旧是“热搜第一”。大家可以根据自己的研究方向,参考最新发布的JCR报告进行投稿选刊。若大家对于投稿选刊方面有任何问题,都可联系张老师为您解答! 相关…

Qt源码阅读笔记:初步了解QtCore模块目录结构

Qt框架是一个跨平台的C应用程序框架,广泛用于开发图形用户界面程序以及用于无界面后台操作的工具和服务器。它由多个模块组成,其中QtCore模块提供了核心的非GUI功能。 QtCore 提供了元对象系统,扩展了c 在元对象系统的基础上,qt又…

timescaledb:创建real-time aggregate

创建hypertable【chz_a】 create table chz_a (time timestamp,device_id int8, value double precision,primary key (time) ); SELECT create_hypertable(chz_a, by_range(time) );往表里面写入数据 # 当天的数据 insert into chz_a (time, device_id, value) values (now(…

七人拼团:互助共赢,电商新动力

在当前繁荣的电商领域中,七人互助拼团模式以其别具一格的激励机制和互助合作理念,成为了消费者和商家共同瞩目的焦点。接下来,我们将详细解读这一模式中的直推激励、滑落补偿以及团队成就奖,并探讨其如何体现互助合作的精神。 一、…

Android面试题:App性能优化之电量优化和网络优化

本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点 电量优化 Doze模式 系统的行为进入Doze后看看App有没有奔溃就可以 Standby待机模式 针对某个应用 处于上述模式,App会无法访问…

Spring Boot中的各种事件

spring boot 各种事件贯穿整个启动的生命周期,读懂了这些事件也差不多理解了springboot的启动流程。 SpringApplicationRunListener中的事件 接口org.springframework.boot.SpringApplicationRunListener定义了spring启动过程中各个事件被触发的顶层方法 public …

内容安全复习 1 - 信息内容安全概述

文章目录 信息内容安全简介网络空间信息内容安全大模型 人工智能简介 信息内容安全简介 网络空间 网络空间是融合物理域、信息域、认知域和社会域,控制实体行为的信息活动空间。 上图展示了网络空间安全的结构。可以看到将网络空间划分为了网络域和内容域两个部分。…

图片的格式怎样在线转换?在线改图片格式的操作技巧

图片作为日常生活中常用的内容展示方式,面对不同的用途图片的格式也是不同的,那么怎样快速完成图片格式转换呢?通过软件来修改图片格式比较麻烦,现在可以在网上使用图片格式转换器工具来在线改图片格式,这种方式会更加…

RK3568技术笔记十六 QT5开发

背景知识 在阅读本章前,如果对下面所列举的知识点有一定的了解,将有助于更好的理解本章内容。 C基础知识,了解简单的类,继承,重载等面向对象概念;Linux基础知识,了解基本的Shell命令&#xff…