当前位置: 首页 > news >正文

传输层协议:UDP和TCP

1.传输层概念

传输层主要负责两台主机之间的数据传输,使数据从发送端到接收端。

端口号

端口号标识了一个主机上进行通信的不同的应用程序。

传输层接收到数据后,是要给到具体的应用层的进程。所以发送端的传输层封装报文时,就要添加上将来会发送到的对端的进程,接收端会在传输层提取出端口号,就可以指定到要发生的进程了。

五元组

在TCP/IP协议中,把源IP,源端口号,目的IP,目的端口号,协议号,这样一个五元组来标识一个通信。

 上图客服端A和B都访问了服务器,A和B的IP地址是不一样的,且客服端A打开了两个浏览器页面,也就是两个进程,两个进程的端口号是不一样的,就可以使用五元组来确保一次通信。

服务器接收到一个五元组,先提取出目的IP和端口号,确定是发送给本服务器,接着提取出协议号来对应给出数据处理,并提取出源IP和源端口号,作为响应数据的目的IP和端口号,数据处理好后就把数据发送回去。

端口号划分

0-1023:知名的端口号,HTTP,FTP,SSH等使用多的应用层协议,它们的端口号都是固定的

1024-65535:操作系统动态分配的端口号,客服端程序的端口号,就是由操作系统从这个范围随机分配的。

2.UDP协议

16位源端口号:数据从来自哪一个进程。

16位目的端口:数据要发送给对端的进程是谁

16位UDP长度:表示整个数据报(UDP首部+UDP数据)的长度

16位UDP检验和:如果UDP检验和出错,就会把报文丢弃

在使用网络编程接口时,端口号类型都是uint16_t,就是因为协议规定的。

UDP报头固定是8个字节大小,收到一个报文时,提取出前八个字节,剩下的就是有效载荷。

在根据报头的16位目的端口的字段,把提取出来的字段交给指定进程。

源代码中的UDP协议

struct udp_hdr
{
    uint16_t src_port;// 源端口
    uint16_t dsc_port;// 目的端口
    uint16_t length;// UDP长度
    uint16_t check;// 校验和
};

 无状态就是无法记忆前一次访问网页

facvion是访问图标

补充

在传输过程中之所以使用变成字节流序列而不是结构体,是因为保证通用性,主机使用的语言不同,使用结构体会收到限制,而字节流序列保证了每一台主机都可以解析这个序列得到信息。

UDP 是一种无连接的协议,它的主要目的是提供一种快速、简单的方式发送数据。它的头部只有 8 个字节,相对于 TCP 来说非常轻量级。UDP 不进行三次握手等复杂操作,数据发送时延迟较低,适合对实时性要求高的应用场景,如实时音频 / 视频流、在线游戏等。如果引入缓冲区和复杂的可靠性机制,会增加协议的复杂性和数据传输的延迟,这与 UDP 的设计目标相悖。

例如,在实时音频通话中,如果数据因为缓冲区和复杂的重传机制而延迟到达,就会导致通话卡顿,影响用户体验。即使丢失少量数据,通过一些前向纠错(FEC)等技术可以在一定程度上弥补,但延迟往往比丢失少量数据的影响更大。

关于报文理解

报文从网卡中接收到,会触发外部引脚触发中断使OS处理报文,而时钟中断是调度进程使应用层来处理报文,网卡接收到数据往上传输,而客服端是很多的,就会有多个报文传输过来,在链路层就会有多个报文,而对于多分报文就需要进行管理,以链表结构进行管理,结构体名字是sk_buff,成员有head指向头空间,data指向应用层数据(有协议头则指向头位置),tail指向应用层数据尾部等,而在应用层开始往下走,结构体的data指针就会移动,添加此协议层的报头,指针的移动就可以控制空间的开辟于缩减,完成了插入于删除的操作,,实现了添加报头域删减报头的方法。

3.TCP协议

这里的4位首部长度表示的是报文大小和选项的大小之和,4为最多15最少0,这里的一个表示的四个字节,也就是4位最大是60个字节,最小0,但是因为报文最小要求的是20个字节,所以4位首部长度最小是5最大15

在tcp中,客服端向服务端发送消息,服务端需要发送应答回去,而此时客服端不需要再发送接收应答回去了,因为发过去服务端又需要发送回来,就死循环了,所以消息需要应答,而接收后返回的应答则不需要回复,而这里的通信于应答都是一个报头。在传输过程中还会出现一个问题,多个消息同时发送,且是有顺序的发送,而接收方是不一定有序接收的,接收方可能接收的是乱序的,所以就需要32位序号来保证有序,根据序号以小到大顺序排,这样就可以使接收的数据有序,而应答方的序号就是发送过去报文的序号+1,这样做是因为服务端也要发送自己的信息过去,顺带了应答,也就是捎带应答,就需要有自己的序号,所以就把发送的序号+1作为自己的序号,这就是为什么有两个序号而不是一个序号,因为服务端也是发了数据过去只不过带了应答。

  • 如果接收方收到的数据不是按顺序的,它会将这些数据暂存在接收缓冲区中,直到缺少的序号的数据到达。例如,如果接收方收到了序号为 501 - 1000 的数据,但还没有收到序号为 1 - 500 的数据,它会将 501 - 1000 的数据暂存,直到收到 1 - 500 的数据后,再将所有数据按顺序组装。

 16位窗口

16位窗口大小表示的发送方自己的接收缓冲区大小,就可以告诉对端自己的还能接收多少,一般是在三次连接中确定了对方的接收大小,根据接收能力来控制发送速度,来提高或者减缓以达到合适区间,这种操作也叫流量控制。

6个标志位

标志位本质就是报头里的bit位,之所有有这个标志位是用来表示这个报文的具体的类型是什么,以做出对应的操作,比如三次连接时就是向发送报文标志位位SYN请求建立连接,SYN是同步标志位,一表示标志位有效。

URG:紧急指针有效

带URG标志位的报文不是正常数据,是带文数据,函数resv的参数flag标志位为MSG_OBB就是表示紧急处理,16位紧急指针类似于数组下标,数组下标也是指针,这里就是一个偏移量,紧急数据只有一个字节方便插队,偏移量的作用是定位紧急数据在报文段中的具体位置,帮助接收方快速找到紧急数据的起始点。紧急指针的值是16位的值,指出了紧急数据的最后一个字节的序列号,然后紧急数据的大小是可以知道的,紧急指针值减去紧急数据的大小就是偏移量了。

    • 应用场景 :当主机需要发送紧急数据(如远程终端操作中的中断命令等),使得接收端能够尽快处理这些紧急数据。例如,在网络管理软件中,管理员可能需要远程紧急停止某个服务。发送方通过设置 URG 标识位并携带紧急指针,将紧急停止命令的指令数据快速发送给接收方,接收方收到后会优先处理这部分紧急数据,而不是像普通数据一样按照先来先到的顺序排队等待处理。

假设客户端的初始序列号X是1000:

  • 第一次握手:客户端发送SYN报文,序列号为1000。SYN标志位占一个序列号,所以下一个数据字节的序列号变为1001。

  • 第二次握手:服务器发送SYN-ACK报文,序列号为2000(服务器的初始序列号),确认号为1001。

  • 第三次握手:客户端发送ACK报文,序列号为1001,确认号为2001。

现在,客户端要发送紧急数据:

  • 客户端设置URG标志位,并在紧急指针字段中填写值为1005。

  • 这意味着紧急数据的最后一个字节的序列号是1005。

  • 当前序列号是1001(因为第三次握手后的序列号是1001),所以紧急数据的大小是1005 - 1001 = 4字节。

ACK:确认号有效

  • 应用场景 :用于确认收到对方发送的数据。在 TCP 通信中,接收方收到发送方的数据后,会根据接收到的数据序列号等信息生成一个确认号,通过设置 ACK 标识位为 1 并携带确认号,告知发送方哪些数据已经成功接收。例如,在一个文件传输过程中,接收方每收到一段数据,就发送一个带有 ACK 标识的报文段给发送方,告诉发送方这部分数据已经收到,发送方可以根据确认号继续发送后续的数据,从而保证数据的可靠传输。

PSH:提示接收端应用程序立刻从TCP缓冲区把数据读走

  • 应用场景 :用于实时性要求较高的数据传输场景。例如,在在线聊天软件中,当用户发送一条消息时,发送方将消息封装在带有 PSH 标识的 TCP 报文中发送。接收方收到后,会立即将消息从 TCP 缓冲区读取并交给聊天软件的应用程序进行处理,这样可以避免消息在接收方缓冲区堆积,确保消息能够及时地显示在接收用户的界面上。

RST:对方要求重新建立连接,携带RST标识叫复位报文段

  • 应用场景 :当服务器检测到某个 TCP 连接异常,如长时间没有数据传输,或者连接的参数出现错误(如端口号错误等),服务器会发送一个带有 RST 标识的报文段给客户端,告知客户端当前连接出现问题,需要重新建立连接。例如,如果一个客户端与服务器建立连接后,由于网络故障导致连接中断,服务器在一定时间内没有收到来自客户端的任何数据,服务器会向客户端发送 RST 报文段,客户端收到后会重新发起连接请求,重新建立与服务器的通信连接。

SYN:请求建立连接,携带SYN标识叫同步报文段

  • 应用场景 :用于建立两个主机之间的 TCP 连接。例如,当用户打开一个网页浏览器并输入一个网址时,浏览器作为客户端会向服务器发送一个带有 SYN 标识的 TCP 报文段,请求与服务器建立连接。服务器收到后会回复一个带有 SYN 和 ACK 标识的报文段,然后客户端再发送一个带有 ACK 标识的报文段,完成三次握手,建立可靠的 TCP 连接后才能进行数据传输。

FIN:通知对方,本端要关闭了,携带FIN标识为结束报文段

  • 应用场景 :用于正常关闭 TCP 连接。例如,在一个文件下载完成后,客户端发送一个带有 FIN 标识的报文段给服务器,告诉服务器客户端已经完成下载,要关闭连接。服务器收到后,会进行相关的清理工作(如关闭文件句柄等),然后回复一个带有 ACK 标识的报文段,之后服务器也可能发送一个带有 FIN 标识的报文段告知客户端自己也准备好关闭连接,客户端再回复 ACK 报文段,完成四次挥手,彻底关闭连接。

4.确认应答机制

第一次握手

客服端发送了TCP报文段,其中SYN标志位置为1,表示开始请求建立连接,报文里面还有初始序列号ISN,服务器收到SYN报文后,就可以知道连接请求的序列号

第二次握手

收到客服端的SYN报文后,同意连接,就发送SYN和ACK标志都为一的报文段作为响应,服务器会现则一个初始序列号放入序列号字段,同时将确认号字段设置为客服端的ISN+1,表示成功接收客服段的SYN报文,比期望接好客服端的下一个数据字节。这里不是序号+1作为发送回去的序号,因为确认序号是对端的序号+1,不然客服端不知道是否接收成功。

  • 序列号(Sequence Number) 是发送方为每个字节的数据分配的唯一编号,用于标识和排序发送的数据。

  • 确认号(Acknowledgment Number) 是接收方告知发送方已经成功接收到的最后一个字节的序列号加一,表示期望接收的下一个字节的序列号。

第三次握手

客服端收到服务器的SYN-ACK报文,发送一个ACK标志位为1的报文端作为确认,这个报文的序列号为ISN+1,这里跟第二次握手的确认序号有关系,因为是期望从这里发送,不是冲突的,确认号为Y+1,是服务端序号+1,表示成功接收到服务器的SYN报文,同时告知服务器期望接收的下一个数据字节。

第三次握手之前都是不发数据的,第三次握手知道对端缓冲区大小,前两次是不携带数据的就可以发送报文过去,也不会浪费资源。

补充初始序列号作用

保证连接唯一性,序号是唯一的,那么以序号连接就是唯一的

数据有序传输,序列号是接收方能够按照正确的顺序接收和重组数据,即使乱序到达也可以重新排序。

防止报文重复,可以做到去重操作,避免重复接好同样报文

超时重传机制

主机A发送数据给B后,可能会因为网络问题,数据无法到达主机B。

如果主机A在一个特定时间间隔内没有收到B发来的确认应答,就会进行重发。

但是主机A没有收到B发来的确认应答,也可能是ACK丢失了,因此主机B会收到很多重复的数据,TCP就需要识别出那些报是重复的包,并丢弃掉重复的。

TCP为了保证无论在任何情况下都能比较高性能的通信,就会动态计算这个最大超时时间,Linux超时以500ms为一个单位进行控制,每次判断超时重发的时间都是500ms整数倍,如果第一次不行,第二次就是2*500ms进行重传,接下来就是4*500ms,累积到一定重传次数,TCP认为网络或者对端主机异常,强制关闭连接。

5.连接管理机制

 

服务端状态转化

closed->listen服务器调用listen进入listen状态,等待客服端连接

 listen->syn_recd一旦听到连接请求(同步报文段),就将该连接放入内核等待队列中,并向客服端发送SYN确认报文

syn_rcvd->established服务端一旦接收到客服端的确认报文,就进入established状态,进行读写数据

established->close_wait当客服端主动关闭连接(调用close),服务器会收到结束报文段,服务器返回确认报文进入close_wait

close->wait->last_ack进入close_wait后说明服务器准备关闭服务器进行关闭连接,当服务器真正调用close关闭连接时,会向客服端发送FIN,此时进入服务器进入last_ack状态,等待最后一个ack到来(是ack是客服端确认收到了FIN)

last_ack->closed服务器收到了对FIN的ack,彻底关闭连接

客服端状态转换

closed->syn_sent客服端调用connect,发送同步报文段

syn_send->established connect调用成功,则进入established状态,开始读写数据

established->fin_wait_1 客服端主动调用close,向服务器发送结束报文,同时进入fin_wait_1

fin_wait_1->fin_wait_2客服端接收到服务器结束报文的确认,则进入fin_wait_2,开始等待服务器的结束报文段

fin_wait_2->time_wait客服端接收到服务器发来的结束报文段,进入time_wait,并发出last_ack

time_wait->closed客服端要等待一个2MSL(Max Segment Life,报文最大生存时间)才会进入closed状态

6.报文管理

服务器在面对多个客服端发来的报文需要进行处理,就用到了队列的数据结构来管理多分报文,通常有一下两种队列,接收队列和发送队列。

接收队列:存储从网络中接收的数据报,数据包到达时,按照到达的顺序放入接收队列,应用程序从队列头部读取数据包进行处理。

发送队列:存储待发送的数据包,应用程序将数据包放入发送队列尾部,网络协议栈从队列头部取数据报发送。

每个客服端都有独立的接收和发送队列,服务端为每一个客服端维护独立的队列,确保客服端的数据不会混淆。

对于多个客服端进行连接,就会有多种连接情况,有的刚进行连接,有的连接一半,有的连接成功,这些连接状态就需要管理起来。

数组:用于存储全连接队列中的连接信息,每一个元素对应一个连接,包含文件描述符,客服端地址,缓冲区指针的等。

全连接和全连接队列

全连接:全连接是指 TCP 三次握手已经完成,客户端和服务端已经建立了完整的通信连接,可以开始双向数据传输。

全连接队列:当客户端和服务端完成三次握手后,该连接会被移到全连接队列中。全连接队列中的每个连接都代表一个已经建立的、可以进行数据传输的连接。服务端为每个全连接分配了必要的资源,例如缓冲区、文件描述符等。

数组用于存储全连接队列中的连接信息

数组是一种基本的数据结构,用于存储多个相同类型的数据项。在全连接队列的管理中,数组可以用来存储每个连接的相关信息。

  • 数组元素对应连接信息:数组的每个元素代表一个全连接。每个元素中存储的信息可能包括:

    • 文件描述符:用于标识和操作该连接的句柄。

    • 客户端地址:记录连接的客户端的网络地址。

    • 缓冲区指针:指向用于存储该连接接收和发送数据的缓冲区。

    • 其他状态信息:如连接建立时间、最后活动时间等。

  • 数组索引的作用:通过数组的索引,可以快速访问和定位特定的连接。如果服务端需要处理某个连接的数据,可以直接通过索引找到对应的数组元素,进而获取该连接的所有相关信息。

  • 动态调整大小的局限性:数组的大小在创建时通常是固定的。如果连接数量超过了数组的大小,就需要创建一个更大的新数组,并将原有数据复制到新数组中,这个过程较为繁琐且可能影响性能。因此,在实际应用中,可能会采用动态数组(如 std::vector 在 C++ 中)来管理全连接队列,以便更方便地动态调整大小。

三次握手补充

三次握手本质是四次,客服端的发送请求SYN,以及应答对端的ACK,发送方的SYN和ACK,但是服务器一般都是无脑接收请求,所以就把应答和连接请求合在一起发送过去了,就变成了三次报文发送,服务器的SYN和ACK合在一起变成捎带应答报文了。

为什么四次挥手不可以合并

因为客服端发送断开连接,服务器并不一定也断开连接,可能还在发送数据,就会延后,发送数据才会发送FIN进行断连请求,所以就不是很好的合并在一起。

关闭连接

全双工表示双方可以同时接收和发送数据,如果一方断开连接变成半连接就是半双工状态。

而在网络连接中,close会释放文件描述符,则对端就无法发送数据给来,因为文件描述符释放就无法读取数据,shutdown函数可以只关闭写端,文件描述符并不会释放,处于半双工状态。

一方断开连接另一端没有断开,没有断开连接的一端就会一直处理close_wait的状态,但是依旧占用文件描述符,就会占用系统资源,占着茅坑不拉屎,导致了文件描述符泄漏问题,达到一定程度就会出现卡顿,进程挂掉现象。

一端先发送FIN进行断连,最后不会马上closed,而是需要等待一定的时间才能处于closed状态,等待过程是处于time_wait状态,处于time_wait的时间是两个报文最大存活时间,之所以是这个时间,因为报文有序号,可能在某个路由器上排队没有丢包但是判断超时了,就会执行超时重传,但是这个报文还是存活中,当客服端关闭重启时,那个报文刚好发送到服务器,而客服端重启连接是各种信息不变(目的ip和源ip等,有概率),服务器就会处理那个旧报文,从而影响连接,导致三次握手失败问题,因为网络上报文时非常多的,基数大的情况下就有可能发生,所以设置两个报文最大存活时间就是保证双方的旧报文都会消散。前面编写的网络代码,服务器打开后在关闭,重新连接就会显示bind error,是因为服务端先关闭的,就会进入到time_wait状态,还没有进入到close状态,连接还是存在的,端口也没有被释放依旧被占用,所以重连需要换一个端口,或者等待一定时间。

  1. 客户端重启连接的相同参数

    • 当客户端重启连接时,如果客户端的 IP 地址、端口号等信息与之前的连接相同,就可能出现旧报文和新连接的冲突。例如,客户端 A 的 IP 地址是 192.168.1.100,端口号是 5000,它与服务器建立了一个连接。当这个连接关闭后,客户端又重新启动连接,并且使用同样的 IP 地址和端口号,就有可能出现旧的报文(在网络中存活的旧报文)和新的连接同时到达服务器。

server的tcp连接在没有完全断开之前不允许重新监听的,某些情况是不合理的

服务器需要处理非常大量的客户端的连接 ( 每个连接的生存时间可能很短 , 但是
每秒都有很大数量的客户端来请求 ).
这个时候如果由服务器端主动关闭连接 ( 比如某些客户端不活跃 , 就需要被服务
器端主动清理掉 ), 就会产生大量 TIME_WAIT 连接 .
由于我们的请求量很大 , 就可能导致 TIME_WAIT 的连接数很多 , 每个连接都会
占用一个通信五元组 ( ip, 源端口 , 目的 ip, 目的端口 , 协议 ). 其中服务器的 ip 和端
口和协议是固定的 . 如果新来的客户端连接的 ip 和端口号和 TIME_WAIT 占用的链
接重复了 , 就会出现问题 .
使用setsockopt()设置socket描述符的选项SO_REUSEDDR为1,表示允许创建端口号相同IP地址不同的多个socket描述符,设置了这个就可以服务器断开重新连接不会出现bind error的错误了。

7.滑动窗口

最开始是每一个发送的字段,都要给一个ACK确认应答,收到ACK后再发送下一个数据段,就会有一个问题,就是性能差,因为应答次数多。
所以就可以进行改进,一次多发送多条数据,就可以提高性能。

窗口大小是指无需等待确认应答而可以继续发送数据的最大值,上图窗口大小就是4000个字节

发送前四个段时,不需要等待任何ACK,直接发送

收到第一个ACK后 ,窗口先后移动,继续发送第五个数据段,依次类推

操作系统内核为了维护这个滑动窗口,需要开辟缓冲区来记录当前还有那些数据没有应答,只有确认过应答的数据,才能从缓冲区中删掉,因为可以会超时重传。

出现丢包情况如何进行重传

情况一:数据包抵达,ACK被弄丢了

 

这种情况下,部分丢了ACK不要紧,会有超时重传机制,发送端会在每个报文后面启动一个超时计算器,会根据网络的往返时间和其变化情况来计算,超时未收到就会重传报文过去,直到收到ACK应答。

情况二:数据包直接丢了

 

当某一段报文丢失后,发送端会一直收到1001这样的ACK,因为1001是丢失的,没有接收到ACK应答,如果发送端主机连续收到3次同样一个“1001”这样的应答,就会将对应的数据1001-2000重新发送,也就是快重传,这个时候接收端收到1001后,再次返回的ACK就是7001,因为前面的2001-7000以及是接收到了,被放到了接收端操作系统内核的缓冲区中。

滑动窗口细节

滑动窗口不会向左滑动,滑动窗口可以变大,变小和不变,不变就是发送过去的数据立即被处理了,这样缓冲区就是原样,为0就说明接收方的接收缓冲区已经满了,无法接收数据。

滑动窗口丢包

1.最左侧丢包

最左侧丢包,其余的发过去,则接收端会返回应答报文,里面的确认序号就是未发送的丢包的数据,会一直发送,发送端就会识别出要执行快重传,重新发送数据包,直到接收到应答,窗口移动,窗口移动的条件是收到应答。

2.中间丢包

中间丢包就说明前面没有丢包,那么前面就会收到应答,滑动窗口就会先右边移动,直到start位置是中间数据发送过去的数据,因为这里是丢失就收不到应答,然后接收端就会一直发送这里的确认序号,就会触发快重传。

补充

滑动窗口是不会溢出的,就像环型队列一样,只要起点和终点位置不一样就说明还可以多发送数据,只要起点和终点位置重合,就说明对端的接收缓冲区到达极限了,就不会扩大了。

第三次握手可以携带数据,第三次握手是应答和数据一起发送过去,对于客服端来说,先发送了请求连接,第二次握手又得到服务端的应答,就说明客服端可以发送数据了,前两次握手也知道了对端的最大接受能力,只是服务端没有接受到应答,这样就可以提高效率。

8.流量控制

接收端处理数据的速度是有限的,发送端太快导致接收缓冲区就会被打满,如果继续发送数据就会导致丢包问题,也会有重传反应出现。TCP支持了根据接收端的处理能力,来决定发送端的发送速度,机制就是流量控制。

通过报文的窗口大小得知对端的缓冲区大小,根据窗口的大小来动态调整发送量。

窗口探测是发送一个没有数据的报文,发送报文就会收到应答,应答报文中就有窗口大小的信息,就可以得知此时对端的接受能力,以便动态调整发送速度,达到合适的传输速度。

流量窗口报文中的放大因子M是用于扩大窗口大小字段的值,从而支持更大的窗口,实际窗口大小字段的值左移M位,就会有窗口的大小字段乘以2的M的次方,M的取值范围通常是0到14,窗口因子可以将窗口大小扩大为31位,使最大窗口的值达到2^30字节左右,提高了16位窗口最大值为65535的问题,可以表示更大的数值。

9.拥塞控制

 发送开始时,定义拥塞窗口大小为1,每次接收到一个ACK应答后,拥塞窗口+1,每次发送数据包时,将拥塞窗口和接收端主机反馈的窗口大小作比较,取较小的值作为实际发送的窗口。

以这样的增长速度,就是拥塞窗口的指数式的慢启动,初始比较慢,但是增长速度比较慢。

少量丢包,仅仅是触发了超时重传,大量丢包,就认为是网络阻塞。

 拥塞的慢启动方案,以指数来增长,指数特性前期增长慢,但是后期增长快。前期慢速增长是为了试探,在危险边缘(阻塞)试探,后面就会慢慢提高速度,达到更快的发送速度,然后到达一个阈值就不在指数增长而是线性增长,这个临界点就是一个阈值,为了支持滑动窗口,就有了一个拥塞窗口,一个int值,小于这个值是大概率不会造成阻塞,大于这个值大概率会造成阻塞。所以滑动窗口的值就是拥塞窗口和对方接收取能力大小两个中最小的哪一个。拥塞窗口的值不会一直增大,而是动态变化的,临界点ssthresh,如果在线性探测中出现了拥塞情况,就会重新回到0出开始慢启动,这次的临界值ssthresh的值就是上一次达到拥塞的值的一半,从新的临界值开始线性探测,临界值是在动态变化的。拥塞窗口的值如果不拥塞,逻辑上就是会一直增长的,但是会受限于物理设备,带宽会影响到实际的发送数据能力,所以拥塞窗口变大与实际发送数据能力不一定变大。

10.延时应答

延时应答机制在接收到报文后,不着急应答,先等待一会,这个时间是在重发时间内,在等待的时间中,上层可能会提取缓冲区的数据,窗口的大小就会变大,就可以让对端发送更多的数据过来,提高了效率。滑动窗口的值受限于拥塞窗口和对端缓冲区大小,有一种可能延时上层提取后的缓冲区大小刚好是滑动窗口可以达到的大小,触发这个的概率很小的,但是网络中基数很大,概率事件就会有实例出现,只要有实例就一定会提高效率,那么这个机制就是有意义的。

延时应答数量限制:每隔N个包应答一次,N一般为2

时间限制:超过最大延迟时间就应答一次,超时时间一般为200ms

11.捎带应答

捎带应答也是为了提高效率,大部分报文都是ACK标志位为1,把应答和数据放在一起发送过去,提高了效率,不用分两次发送过去。

12.粘包问题

粘包问题是数据一次新发送不过去,发送的数据大于对端缓冲区接收大小,就需要多次分段发送过去,而多次发送就需要保证能取出完整数据,就需要协议来处理,明确报文和报文之间的边界线,还需要序列化和反序列化参与,保证了分段传输,对端能完整提取数据。

13.异常情况

1.一端直接退出,另一端未退出

一端退出就无法接收对端发过来的数据,而对端就会触发超时重传机制去一直发送数据,直到达到了一定的次数,就会认定对端处于断开连接的状态,从而关闭连接。

2.一端退出连接后马上重连

数据传输恢复

若在网络修复前,另一端因连接异常而处于等待状态,网络修复后,只要连接尚未被终止,另一端就会继续按照TCP协议栈的机制进行数据传输,之前发送的数据因故障未收到对端的确认应答,网络恢复后,另一端会重新发送之前未被确认的数据,等待对端的应答,从而恢复通信。

连接状态恢复

网线故障期间,另一端以及将连接判断位不可用并准备关闭连接,那么在网线修复后,另一端可能根据连接状态来决定是否重新建立连接。如果重新连接时,对端还在超时重传,当网络恢复后并收到对端的响应后,连接可能恢复到正常工作状态,而不用重新建立连接。

如果已经过了超时重传的时间,开始执行连接关闭的流程,网络恢复也处于连接关闭状态,另一端就需要重新发起建立连接过程,才能与对端重新建立通信。

14.TCP保活机制

发送保活探测报文,当连接处于空闲状态时,也就是一定时间没有发送数据,保活机制会定期发送保活探测报文。报文通常是一些小的TCP数据包,不包含实际的应用数据。

保活时间间隔:保护探测报文的发送数间间隔可以配置,常见的保活时间间隔为2个小时。

保活探测次数:如果连续发送多个保活数据报文后并没有收到对端的响应,TCP协议栈会认为连接已经断开,并关闭连接,通常默认值是三次保活探测报文。(TCP协议栈是操作系统中实现TCP协议及相关功能的软件模块集合,负责处理TCP协议相关的操作)

相关文章:

传输层协议:UDP和TCP

1.传输层概念 传输层主要负责两台主机之间的数据传输,使数据从发送端到接收端。 端口号 端口号标识了一个主机上进行通信的不同的应用程序。 传输层接收到数据后,是要给到具体的应用层的进程。所以发送端的传输层封装报文时,就要添加上将来…...

[Linux] Linux线程信号的原理与应用

Linux线程信号的原理与应用 文章目录 Linux线程信号的原理与应用**关键词****第一章 理论综述****第二章 研究方法**1. **实验设计**1.1 构建多线程测试环境1.2 信号掩码策略对比实验 2. **数据来源**2.1 内核源码分析2.2 用户态API调用日志与性能监控 **第三章 Linux信号的用法…...

MySQL 库的操作 -- 字符集和校验规则,库的增删查改,数据库的备份和还原

目录 1. 字符集和校验规则 1.1 查看系统默认字符集以及检验规则 1.2 查看数据库支持的字符集 1.3 查看数据库支持的字符集检验规则 1.4 校验规则对数据库的影响 2. 数据库的操作 2.1 创建数据库 2.1.1 语法 2.1.2 示例 2.2 查看数据库 2.2.1 语法 2.2.2 查看当前使…...

Opencv常见学习链接(待分类补充)

文章目录 1.常见学习链接 1.常见学习链接 1.Opencv中文官方文档 2.Opencv C图像处理:矩阵Mat 随机数RNG 计算耗时 鼠标事件 3.Opencv C图像处理:亮度对比度饱和度高光暖色调阴影漫画效果白平衡浮雕羽化锐化颗粒感 4.OpenCV —— 频率域滤波&#xff…...

Docker网络全景解析:Overlay与Macvlan深度实践,直通Service Mesh集成核心

一、Docker网络基石:从单机到跨主机的本质跨越 1.1 网络模式全景图 Docker原生网络架构: ├─ 单机网络(默认) │ ├─ bridge:默认NAT模式(docker0网桥) │ ├─ host:共…...

十五、面向对象底层逻辑-BeanDefinitionRegistryPostProcessor接口设计

一、引言:Spring容器启动的核心枢纽 在Spring容器的启动过程中,BeanDefinitionRegistryPostProcessor接口是开发者深度介入Bean定义注册阶段的核心扩展点。作为BeanFactoryPostProcessor的子接口,它赋予了开发者对BeanDefinitionRegistry的直…...

图表组件库TeeChart Pro VCL/FMX :简化复杂数据处理的可视化利器

在数据驱动决策的时代,把复杂的数据转化为直观、易懂的图表,是很多人都面临的挑战。TeeChart Pro VCL/FMX 就是一款能帮你解决这个难题的强大工具,它为开发者和数据分析师提供了丰富的功能,让数据可视化变得简单又高效。 一、丰富…...

从客厅到驾驶舱:FSHD 如何成为全场景显示「破局者」

一、当显示技术遇到「场景困境」:传统方案的三大痛点 周末午后的客厅,阳光透过纱窗洒在幕布上,传统投影机的画面瞬间发白;高速公路上,车载 HUD 在强光下字迹模糊,驾驶员不得不频繁低头看仪表盘;…...

时源芯微|开关电源电磁干扰的控制技术

要有效解决开关电源的电磁干扰问题,可从以下三个关键方面着手:其一,降低干扰源产生的干扰信号强度;其二,阻断干扰信号的传播路径;其三,提升受干扰体的抗干扰能力。基于此,开关电源电…...

动态规划之爬楼梯模型

文章目录 爬楼梯模型LeetCode 746. 使用最小花费爬楼梯思路Golang 代码 LeetCode 377. 组合总和 Ⅳ思路Golang 代码 LeetCode 2466. 统计构造好字符串的方案数思路Golang 代码 LeetCode 2266. 统计打字方案数思路Golang 代码 爬楼梯模型 爬楼梯模型是动态规划当中的一个经典模型…...

图论学习笔记 3

自认为写了很多,后面会出 仙人掌、最小树形图 学习笔记。 多图警告。 众所周知王老师有一句话: ⼀篇⽂章不宜过⻓,不然之后再修改使⽤的时候,在其中找想找的东⻄就有点麻烦了。当然⽂章也不宜过多,不然想要的⽂章也不…...

进阶知识:自动化测试框架开发之无参的函数装饰器

进阶知识:自动化测试框架开发之无参的函数装饰器 from functools import wrapsdef func_2(func):"""无参的函数装饰器:param func::return:"""wraps(func)def wrap_func(*args, **kwargs):print(开始执行: func.__name__…...

【实验增效】5 μL/Test 高浓度液体试剂!Elabscience PE Anti-Mouse Ly6G抗体 简化流式细胞术流程

产品概述 Elabscience 推出的 PE Anti-Mouse Ly6G Antibody (1A8, 货号: E-AB-F1108D) 是一款高特异性、高灵敏度的流式抗体,专为小鼠中性粒细胞(Ly6G⁺细胞)的精准检测而设计。该抗体采用PE(藻红蛋白)标记&#xff0…...

多模态光学成像革命:OCT、荧光与共聚焦的跨尺度融合新范式

一、技术融合的必然性 在生物医学成像领域,单一模态往往存在视野-分辨率悖论。光学相干断层扫描(OCT)虽能实现毫米级深度扫描(1010mm视野),但其微米级分辨率难以解析亚细胞结构;荧光显微成像(FMI)虽具有分子特异性标记优势(88mm中观视野),却受限于光毒性及穿透深度…...

CHI中ordering的抽象

上图是一个典型的读操作过程中的几个流程,其中: compdata, 这个就是CHI协议保序之Comp保序-CSDN博客中提到的,comp保序,它实现的功能是,通知这个请求的RN, 你的请求,我已经开始处理了,同时也相当…...

华为云Flexus+DeepSeek征文 | 基于ModelArts Studio 与 Cline 快速构建AI编程助手

目录 一、前言 二、ModelArts Studio(MaaS)介绍与应用场景 2.1ModelArts Studio(MaaS)介绍 2.2 ModelArts Studio(MaaS)使用场景 2.3 开通MaaS服务 2.4 开通DeepSeek-V3商用服务 三、Cline简介和安装 3.1 C…...

第二章 何谓第二大脑?笔记记录

2025/05/08 发表想法 用词太准确了,从信息过载-信息倦怠,正是我们当今社会信息工作者中正在经历的事情,同时大部分人也正在产生焦虑、不安、失眠等社会现象。 原文:然而信息的泛滥,非但难以起到赋能作用,反…...

题解:AT_abc244_e [ABC244E] King Bombee

一道图上 DP 的好题。 (题目自己看,我就不说了。) 首先一看到求方案数,首先就要反应的是 DP 或者排列组合,反正考试的时候我写半天排列组合没写出来,所以就只能是 DP 了。(好牵强的理由啊………...

C++显式声明explicit

C显示声明explicit 在 C 中,explicit 关键字用于修饰单参数构造函数或多参数构造函数(C11 起),其核心作用是禁止编译器的隐式类型转换。 一、必须加 explicit 的典型场景 1. 单参数构造函数 当构造函数只有一个参数时&#xff…...

哈希查找方法

已知哈希表长度为11,哈希函数为H(key)=key%11,随机产生待散列的小于50的8个元素,同时采用线性探测再散列的方法处理冲突。任意输入要查找的数据,无论是否找到均给出提示信息。 int f…...

AI编程辅助哪家强?深度解析主流AI编程工具的现状与未来-优雅草卓伊凡

AI编程辅助哪家强?深度解析主流AI编程工具的现状与未来-优雅草卓伊凡 引言:AI编程的崛起与开发者的新选择 在当今快速发展的科技时代,AI编程辅助工具已经成为开发者不可或缺的得力助手。作为一名资深的程序员,”优雅草卓伊凡”经…...

Python打卡训练营day27-函数-装饰器

知识点回顾: 装饰器的思想:进一步复用函数的装饰器写法注意内部函数的返回值 作业: 编写一个装饰器 logger,在函数执行前后打印日志信息(如函数名、参数、返回值) 装饰器实际上是一个增强函数,它…...

EtherCAT通信协议

EtherCAT(Ethernet for Control Automation Technology)是一种高性能的实时工业以太网通信协议,专为工业自动化和控制系统的需求设计。它结合了以太网的灵活性和工业实时通信的高效性,广泛应用于运动控制、机器人、过程自动化等领…...

多线程下如何保证事务的一致性

以下是关于Java多线程的详细介绍,适合作为知识博客的内容。我将从基础概念开始,逐步深入到分布式场景、线程池配置以及Spring Cloud集成等高级主题,并提供丰富的业务场景示例。 Java多线程核心概念 1. 线程与进程的区别 进程:程…...

OpenCv高阶(8.0)——答题卡识别自动判分

文章目录 前言一、代码分析及流程讲解(一)初始化模块正确答案映射字典(题目序号: 正确选项索引)图像显示工具函数 (二)轮廓处理工具模块(三)几何变换核心模块 二、主处理流程图像读取…...

量子通信技术:原理、应用与未来展望

在当今数字化时代,信息安全是全球关注的焦点。随着量子计算技术的飞速发展,传统的加密方法面临着前所未有的挑战。量子通信技术作为一种新兴的通信手段,以其绝对安全的特性,为信息安全领域带来了新的希望。本文将深入探讨量子通信…...

Token的组成详解:解密数字身份凭证的构造艺术

在当今的互联网身份认证体系中,Token如同数字世界的"安全护照",承载着用户的身份信息和访问权限。据统计,现代应用中80%以上的身份验证依赖于Token机制。本文将深入解析Token的各个组成部分,通过典型实例揭示其设计原理…...

【SFT监督微调总结】大模型SFT全解析:从原理到工具链,解锁AI微调的核心密码

文章目录 一. 什么是监督微调(SFT)?二. SFT的核心原理与流程2.1 基本原理2.2 训练流程三、SFT训练的常用方法四、SFT训练用的数据格式4.1、基础单轮指令格式1. Alpaca 格式2. 单轮QA格式3. 代码-注释对4.2、多轮对话格式1. ShareGPT 格式2. 层次化对话格式3. 角色扮演对话4.…...

MacBook Air A2179(Intel版)安装macOS Catalina所需时间

MacBook Air A2179(Intel版)安装macOS Catalina所需时间如下: 一、标准安装时间范围 常规安装(通过App Store) • 下载时间:约30-60分钟(取决于网络速度,安装包约8GB) •…...

Git的windows开发与linux开发配置

Git的基本配置 安装 linux可以使用包管理器安装windows可以使用 mingw的git:https://git-scm.com/downloadsTortoiseGit:https://tortoisegit.org/download/ 配置 分为系统配置–system、全局配置–global、项目配置–local 配置名称和邮箱 git co…...

使用Mathematica绘制一类矩阵的特征值图像

学习过线性代数的,都知道:矩阵的特征值非常神秘,但却携带着矩阵的重要信息。 今天,我们将展示:一类矩阵,其特征值集体有着很好的分布特征。 modifiedroots[c_List] : Block[{a DiagonalMatrix[ConstantAr…...

C++中的宏

0 资料 最值宏do{}while(0)的宏封装技巧 1 最值宏 - C最值的宏,在两个头文件中,分别为cfloat和climits。其中,float的最值宏在cfloat中,且cfloat没有负值的最小宏,而其他char、int和double是在climits中。如下// --…...

谷粒商城的三级分类实现

先查出全部的数据再分类 分类的一级分类是根据数据的Parent_id进行确定的&#xff0c;所以要进行筛选&#xff1a; 主方法&#xff1a; public List<CategoryEntity> listWithTree() {//1.查出所有分类List<CategoryEntity> entities baseMapper.selectList(nul…...

基于大模型预测的闭合性髌骨骨折诊疗全流程研究报告

目录 一、引言 1.1 研究背景与目的 1.2 研究意义与价值 二、大模型预测原理与方法 2.1 大模型概述 2.2 预测方法与数据输入 2.3 模型训练与优化 三、术前预测分析 3.1 骨折类型预测 3.2 损伤程度评估 3.3 潜在风险预测 四、手术方案制定 4.1 传统手术方案对比 4.…...

基于CodeBuddy的Craft完成一个数字华容道的小游戏

参考 CodeBuddy&#xff0c;AI 时代的智能编程伙伴 插件功能入门 总结 本文主要基于CodeBuddy的Craft 完成一个数字华容道的小游戏&#xff0c;如果读者还不清楚怎么安装&#xff0c;在本文的前面附上了CodeBuddy 编程助手的安装步骤。读者可以根据需求自行确定从那开始。 …...

一文掌握vue3基础,适合自学入门案例丰富

Vue3 本文从Vue3的基础语法出发&#xff0c;全面系统的介绍了Vue3的核心概念与应用&#xff0c;旨在帮助自学者更轻松地掌握Vue3。文章内容由浅入深&#xff0c;从通过CDN引入Vue3开始&#xff0c;逐步介绍了组合式API、模块化开发、以及常见的Vue3指令和功能并从单个html的使…...

OpenHarmony 5.0设置应用设置手势导航开关打开后重新关闭导航栏和设置界面重合

目录 1.背景 2.解决方案 1.背景 在OpenHarmony 5.0中从设置界面打开手势导航开关然后重新关闭&#xff0c;此时设置界面导航栏和设置列表主界面重合&#xff0c;导致设置界面无法点击最下面的关于设备 2.解决方案 首先参考之前的如何设置导航栏文档&#xff0c;我们可以自己…...

[ARM][汇编] 02.ARM 汇编常用简单指令

目录 1.数据传输指令 MRS - Move from Status Register 指令用途 指令语法 代码示例 读取 CPSR 到通用寄存器 在异常处理程序中读取 SPSR 使用场景 MSR - Move to Status Register 指令语法 使用场景 示例代码 改变处理器模式为管理模式 设置条件标志位 异常处理…...

系统架构设计(十七):微服务数据一致性和高可用策略

数据一致性问题 问题本质 由于每个微服务拥有独立数据库&#xff0c;跨服务操作不能用传统的数据库事务&#xff0c;面临“分布式事务”一致性挑战。 数据一致性策略 策略核心思想应用场景优缺点强一致性&#xff08;Strong Consistency&#xff09;所有操作实时同步成功&a…...

[Harmony]获取设备参数

获取屏幕宽度/屏幕高度/状态栏高度/导航栏高度/刘海高度/设备型号/系统版本号... DevicesUtil import window from ohos.window; import { common } from kit.AbilityKit; import display from ohos.display; import deviceInfo from ohos.deviceInfo; import i18n from ohos.…...

Python60日基础学习打卡D31

如何把一个文件&#xff0c;拆分成多个具有着独立功能的文件&#xff0c;然后通过import的方式&#xff0c;来调用这些文件&#xff1f;这样具有几个好处&#xff1a; 可以让项目文件变得更加规范和清晰可以让项目文件更加容易维护&#xff0c;修改某一个功能的时候&#xff0…...

命名常量集合接口INamedConstantCollection<T>实现

public interface INamedConstantCollection<TObject, TName> : IEnumerable<TObject>, IEnumerable where TName : IComparable{TObject this[TName name] { get; }TObject this[int index] { get; }int Count { get; }int Capacity { get; }} 这是一个泛型接口&…...

TYUT-企业级开发教程-第6章

这一章 考点不多 什么是缓存&#xff1f;为什么要设计出缓存&#xff1f; 企业级应用为了避免读取数据时受限于数据库的访问效率而导致整体系统性能偏低&#xff0c;通 常会在应用程序与数据库之间建立一种临时的数据存储机制&#xff0c;该临时存储数据的区域称 为缓存。缓存…...

反射在spring boot自动配置的应用

目录 一&#xff0c;背景 二&#xff0c;知识回顾 2.1 理解使用反射技术&#xff0c;读取配置文件创建目标对象&#xff08;成员变量&#xff0c;方法&#xff0c;构造方法等&#xff09; 三&#xff0c;springboot自动配置 3.1 反射在自动配置中的工作流程 3.2 浏览源码…...

项目进度延误,如何按时交付?

项目进度延误可以通过加强计划管理、优化资源分配、强化团队沟通、设置关键里程碑和风险管理机制等方式来实现按时交付。加强计划管理、优化资源分配、强化团队沟通、设置关键里程碑、风险管理机制。其中&#xff0c;加强计划管理尤为关键&#xff0c;因为明确而详细的计划能提…...

内网穿透:轻松实现外网访问本地服务

异步通知的是需要通过外网的域名地址请求到的&#xff0c;由于我们还没有真正上线&#xff0c;那支付平台如何请求到我们本地服务的呢&#xff1f; 这里可以使用【内网穿透】技术来实现&#xff0c;通过【内网穿透软件】将内网与外网通过隧道打通&#xff0c;外网可以读取内网…...

缺乏进度跟踪机制,如何掌握项目状态?

要有效掌握项目状态&#xff0c;必须建立明确的进度跟踪机制、使用专业的项目管理工具、定期召开沟通会议、设立清晰的关键里程碑和实施风险监控。其中&#xff0c;建立明确的进度跟踪机制是关键&#xff0c;通过系统地追踪项目各个阶段的完成情况&#xff0c;及时发现问题并采…...

ES 调优帖:关于索引合并参数 index.merge.policy.deletePctAllowed 的取值优化

最近发现了 lucene 9.5 版本把 merge 策略的默认参数改了。 * GITHUB#11761: TieredMergePolicy now allowed a maximum allowable deletes percentage of down to 5%, and the defaultmaximum allowable deletes percentage is changed from 33% to 20%. (Marc DMello)也就是…...

基于 STM32 单片机的实验室多参数安全监测系统设计与实现

一、系统总体设计 本系统以 STM32F103C8T6 单片机为核心,集成温湿度监测、烟雾检测、气体泄漏报警、人体移动监测等功能模块,通过 OLED 显示屏实时显示数据,并支持 Wi-Fi 远程传输。系统可对实验室异常环境参数(如高温、烟雾、燃气泄漏)及非法入侵实时报警,保障实验室安…...

Spring Boot-Swagger离线文档(插件方式)

Swagger2Markup简介 Swagger2Markup是Github上的一个开源项目。该项目主要用来将Swagger自动生成的文档转换成几种流行的格式以便于静态部署和使用&#xff0c;比如&#xff1a;AsciiDoc、Markdown、Confluence。 项目主页&#xff1a;https://github.com/Swagger2Markup/swagg…...