首页 > 其他分享 >UDP的可靠性传输——KCP

UDP的可靠性传输——KCP

时间:2024-08-19 09:22:15浏览次数:9  
标签:UDP 可靠性 窗口 重传 ACK 发送 分组 KCP 接收

目录

一:TCP是怎么做到可靠的?

1、UDP和TCP的区别

 2、ARQ协议(Automatic Repeat-reQuest)

2.1、ARQ协议-停等式(stop-and-wait)

2.2、ARQ协议-回退n帧(go-back-n)

2.3、ARQ协议-选择性重传(selective repeat)

3、RTT和RTO

4、流量控制

5、如何进行流量控制(滑动窗口)

6、流量控制小结

7、拥塞控制

二:KCP如何让UDP可靠

1、RTO翻倍 vs 不翻倍

2、选择性重传 vs 全部重传

3、快速重传

4、延迟ACK vs 非延迟ACK

5、UNA vs ACK+UNA

6、非退让流控

三:kcp的使用

1、使用方式

2、udp的并发编程

3、KCP协议头


一:TCP是怎么做到可靠的?

1、UDP和TCP的区别

 2、ARQ协议(Automatic Repeat-reQuest)

        在网络中,我们认为传输是不可靠的,而在很多场景下我们需要的是可靠的数据, 所谓的可靠,指的是数据能够正常收到,且能够顺序收到,于是就有了ARQ协议, TCP之所以可靠就是基于此。

        ARQ协议(Automatic Repeat-reQuest),即自动重传请求,是传输层的错误纠正协议之一,它通过使用确认和超时两个机制,在不可靠的网络上实现可靠的信息传输。

2.1、ARQ协议-停等式(stop-and-wait)

1、发送方对接收方发送数据包,然后等待接收方回复ACK并且开始计时。

2、在等待过程中,发送方停止发送新的数据包。

3、当数据包没有成功被接收方接收,接收方不会发送ACK.这样发送方在等待一 定时间后,重新发送数据包。

4、反复以上步骤直到收到从接收方发送的ACK。

 缺点:较长的等待时间导致低的数据传输速度。

2.2、ARQ协议-回退n帧(go-back-n)

        (1)、为了克服停等式协议长时间等待ACK的缺陷,连续ARQ协议会连续发送一组数据包,然后再等待这些数据包的ACK。

        (2)、什么是滑动窗口:发送方和接收方都会维护一个数据帧的序列,这个序列被称作窗口。发送方的 窗口大小由接收方确定,目的在于控制发送速度,以免接收方的缓存不够大,而导致溢出,同时控制流量也可以避免网络拥塞。协议中规定,对于窗口内未经确认的分组需要重传。

        (3)、回退N步(Go-Back-N,GBN):回退N步协议允许发送方在等待超时的间歇,可以继续发送分组。所有发送的分组,都带有序号。在GBN协议中,发送方需响应以下三种事件:

1、上层的调用。上层调用相应send()时,发送方首先要检查发送窗口是否已满。

2、接收ACK。在该协议中,对序号为n的分组的确认采取累积确认的方式,表明接收方已 正确接收到序号n以前(包括n)的所有分组。

3、超时。若出现超时,发送方将重传所有已发出但还未被确认的分组。

        (4)、具体的流程:对于接收方来说,若一个序号为n的分组被正确接收,并且按序,则接收方会为该分组返 回一个ACK给发送方,并将该分组中的数据交付给上层。在其他情况下,接收方都会丢弃 分组。若分组n已接收并交付,那么所有序号比n小的分组也已完成了交付。

        因此GBN采用 累积确认是一个很自然的选择。发送方在发完一个窗口里的所有分组后,会检查最大的有 效确认,然后从最大有效确认的后一个分组开始重传。

         总结:GBN采用的技术包括序号、累积确认、检验和以及计时/重传。虽然GBN改善了停等协议中时间等待较长的缺陷,但它依旧存在着性能问题。特别是当窗口长度很大的时候,会使效率大大降低。

2.3、ARQ协议-选择性重传(selective repeat)

        SR协议通过让发送方仅重传在接收方丢失或损坏了的分组,从而避免了不必要的重传,提高了效率。

        在SR协议下,发送方需响应以下三种事件:

        1、从上层收到数据:当从上层收到数据后,发送方需检查下一个可用于该分组的 序号。若序号在窗口中则将数据发送。

        2、接收ACK:若收到ACK,且该分组在窗口内,则发送方将那个被确认的分组标记 为已接收。若该分组序号等于基序号,则窗口序号向前移动到具有最小序号的未确认分组处。若窗口移动后并且有序号落在窗口内的未发送分组,则发送这些分组。

        3、超时:若出现超时,发送方将重传已发出但还未确认的分组。与GBN不同的是, SR协议中的每个分组都有独立的计时器。

         在SR协议下,接收方需响应以下三种事件: (假设接收窗口的基序号为4,分组长度也为4)

        1、序号在[4,7]内的分组被正确接收。该情况下,收到的分组落在接收方的窗口内,一个ACK 将发送给发送方。若该分组是以前没收到的分组,则被缓存。若该分组的序号等于基序号4, 则该分组以及以前缓存的序号连续的分组都交付给上层,然后,接收窗口将向前移动。

        2、序号在[0,3]内的分组被正确接收。在该情况下,必须产生一个ACK,尽管该分组是接收方 以前已确认过的分组。若接收方不确认该分组,发送方窗口将不能向前移动。

        3、其他情况。忽略该分组 对于接收方来说,若一个分组正确接收而不管其是否按序,则接收方会为该分组返回一个ACK 给发送方。失序的分组将被缓存,直到所有丢失的分组都被收到,这时才可以将一批分组按 序交付给上层。

3、RTT和RTO

RTO(Retransmission TimeOut)即重传超时时间。

RTT(Round-Trip Time): 往返时延。表示从发送端发送数据开始,到发送端收到来自接收端的确认(接收端收到数据后便立即发送确认),总共经历的时延。

 RTT由三部分组成

1、链路的传播时间(propagation delay)

2、末端系统的处理时间

3、路由器缓存中的排队和处理时间(queuing delay)

        其中,前两个部分的值对于一个TCP连接相对固定,路由器缓存中的排队和处理时间会随着整个网络拥塞程度的变化而变化。 所以RTT的变化在一定程度上反应网络的拥塞程度。

4、流量控制

        双方在通信的时候,发送方的速率与接收方的速率是不一定相等,如果发送方 的发送速率太快,会导致接收方处理不过来,这时候接收方只能把处理不过来 的数据存在缓存区里(失序的数据包也会被存放在缓存区里)接收缓存。

        如果缓存区满了发送方还在疯狂着发送数据,接收方只能把收到的数据包丢掉,大量的丢包会极大着浪费网络资源,因此,我们需要控制发送方的发送速率, 让接收方与发送方处于一种动态平衡才好。

        对发送方发送速率的控制,称之为流量控制。公平使用带宽100M 10个10M左右。

5、如何进行流量控制(滑动窗口)

        接收方每次收到数据包,可以在发送确定报文的时候,同时告诉发送方自己的缓存区还剩余多少 是空闲的,我们也把缓存区的剩余大小称之为接收窗口大小,用变量win来表示接收窗口的大小。

        发送方收到之后,便会调整自己的发送速率,也就是调整自己发送窗口的大小,当发送方收到接收窗口的大小为0时,发送方就会停止发送数据,防止出现大量丢包情况的发生。

        当发送方停止发送数据后,该怎样才能知道自己可以继续发送数据?

        当接收方处理好数据,接受窗口 win > 0 时,接收方发个通知报文去通知发送方,告诉他可以继续发送数据了。当发送方收到窗口大于0的报文时,就继续发送数据。

        当发送方收到接受窗口 win = 0 时,这时发送方停止发送报文,并且同时开启一个定时器,每隔一段时间就发个测试报文去询问接收方,打听是否可以继续发送数据了,如果可以,接收方就告诉他此时接受窗口的大小;如果接受窗口大小还是为0,则发送方再次刷新启动定时器。

6、流量控制小结

        1.通信的双方都拥有两个滑动窗口,一个用于接受数据,称之为接收窗口;一个用于发送数据,称之为拥塞窗口(即发送窗口)。指出接受窗口大小的通知我们称之为窗口 通告。

        2. 接收窗口的大小固定吗?接受窗口的大小是根据某种算法动态调整的。

        3. 接收窗口越大越好吗?当接收窗口达到某个值的时候,再增大的话也不怎么会减少丢包率的了,而且还会更加消耗内存。所以接收窗口的大小必须根据网络环境以及 发送发的的拥塞窗口来动态调整。

        4. 发送窗口和接收窗口相等吗?接收方在发送确认报文的时候,会告诉发送发自己的接收窗口大小,而发送方的发送窗口会据此来设置自己的发送窗口,但这并不意味 着他们就会相等。首先接收方把确认报文发出去的那一刻,就已经在一边处理堆在 自己缓存区的数据了,所以一般情况下接收窗口>= 发送窗口

7、拥塞控制

        拥塞控制和流量控制虽然采取的动作很相似,但拥塞控制与网络的拥堵情况相关联,而流量控制与接收方的缓存状态相关联。

二:KCP如何让UDP可靠

1、RTO翻倍 vs 不翻倍

        TCP超时计算是RTOx2,这样连续丢三次包就变成RTOx8了,十分恐怖,而KCP启动快 速模式后不x2,只是x1.5(实验证明1.5这个值相对比较好),提高了传输速度。 以RTO=100ms为例:

2、选择性重传 vs 全部重传

        TCP丢包时会全部重传从丢的那个包开始以后的数据,KCP是选择性重传(SR),只重传真正丢失的数据包。

3、快速重传

        跳过多少个包马上重传,使用了快速重传,可以不考虑RTO。发送端发送了1,2,3,4,5几个包,然后收到远端的ACK: 1, 3, 4, 5,当收到ACK3时,KCP 知道2被跳过1次,收到ACK4时,知道2被跳过了2次,此时可以认为2号丢失,不用等超时,直接重传2号包,大大改善了丢包时的传输速度。

4、延迟ACK vs 非延迟ACK

        TCP为了充分利用带宽,延迟发送ACK(NODELAY-针对发送的都没用),这样超时计算会算出较大RTT时间,延长了丢包时的判断过程。KCP的ACK是否延迟发送可以调节。

5、UNA vs ACK+UNA

        ARQ模型响应有两种,UNA(此编号前所有包已收到,如TCP)和ACK(该编号包已收到),光用UNA将导致全部重传,光用ACK则丢失成本太高,以往协议都是二选其一, 而KCP协议中,除去单独的ACK包外,所有包都有UNA信息。

6、非退让流控

        KCP正常模式同TCP一样使用公平退让法则,即发送窗口大小由:发送缓存大小、接收端剩余接收缓存大小、丢包退让及慢启动这四要素决定。但传送及时性要求很高的小数据时,可选择通过配置跳过后两步,仅用前两项来控制发送频率。以牺牲部分公平性及带宽利用率之代价,换取了开着BT都能流畅传输的效果。

三:kcp的使用

1、使用方式

1.1:创建KCP对象:ikcpcb *kcp = ikcp_create(conv, user);

1.2:设置发送回调函数(如UDP的send函数):kcp->output = udp_output; 但是真正发送数据需要调用sendto。

1.3:循环调用update:ikcp_update(kcp, millisec); //在一个线程、定时器5ms/10m做调度

1.4:输入一个应用层数据包(如UDP收到的数据包):ikcp_input(kcp,received_udp_packet,received_udp_size); 但是需要我们使用recvfrom接收,然后扔到kcp里面做解析。

1.5:发送数据:ikcp_send(kcp1, buffer, 8); 在这里做用户层接口。

1.6:接收数据:hr = ikcp_recv(kcp2, buffer, 10); 在这里用户层读取数据。

2、udp的并发编程

         UDP相比TCP中,是不存在listen和accept的,面向无连接的。那要怎么进行并发编程呢?

        我们可以在客户端发送数据包的前面存放conv会话id,表示从哪里发送来的数据,代表一种连接。但是每个客户端和服务端之间都会产生一个udp_socket通道。但是这个会话id是由客户端写入的,会不会出现一种情况,导致两个客户端之间存在一样的会话id呢?

        确实会存在这样的情况发生。但是我们可以通过uuid算法,生成唯一的id。当然我们可以让服务端产生唯一的会话id,让客户端通过http向服务端请求一个会话id。

3、KCP协议头

[0,3]conv:连接号UDP是无连接的,conv用于表示来自于哪个客户端。对连接的一种替代
[4]cmd:命令字IKCP_CMD_ACK确认命令, IKCP_CMD_WASK接收窗口大小询问命令,IKCP_CMD_WINS接收 窗口大小告知命令
[5]frg:分片用户数据可能会被分成多个KCP包,发送出去
[6,7]wnd接收窗口大小,发送方的发送窗口不能超过接收方给出的数值
[8,11]ts时间序列
[12,15]sn序列号
[16,19]una下一个可接收的序列号。其实就是确认号,收到 sn=10的包,una为11
[20,23]len数据长度
data用户数据,这一次发送的数据长度

具体的源码需要自己去看哦,感谢大家的收看!https://xxetb.xetslk.com/s/2D96kH

标签:UDP,可靠性,窗口,重传,ACK,发送,分组,KCP,接收
From: https://blog.csdn.net/2301_76446998/article/details/141286560

相关文章

  • 【TCP/IP】UDP协议数据格式和报文格式
    学习一个网络协议,主要就是学习“数据格式”/“报文格式”源端口/目的端口端口号是属于传输层的概念UDP报头使用两个自己的长度来表示端口号之所以端口号的范围是0~65535,是因为底层网络协议做出了强制要求如果使用一个10w这样的端口,就会在系统底层被“截断”UDP......
  • RabbitMQ实现消息可靠性的三种方法(发送者可靠性,MQ可靠性,消费者可靠性)
    1.发送者可靠性1.1发送者重连RabbitMQ的发送者重连机制是一种应对网络不稳定或连接中断情况的策略,它能够自动尝试重新建立与RabbitMQ服务器的连接,以确保消息能够成功发送。发送者重连通常涉及到一些配置参数,如连接超时时间、重试间隔、最大重试次数等。例如,在Spring框架的......
  • 浅谈TCP协议、UDP协议
    一、介绍说明TCP(传输控制协议)面向连接:TCP在数据传输之前必须建立连接。这通过一个称为三次握手的过程来完成,确保连接的两端都准备好进行数据传输。可靠性:TCP提供可靠的数据传输,确保数据包正确无误地到达目的地。如果数据包在传输过程中丢失或损坏,TCP会重新发送这些数据包......
  • TCP/UDP网络聊天室
        本博客仅对网络聊天室项目进行分享,仅供学习讨论使用,欢迎大家讨论。UDP网络聊天室项目要求        利用UDP协议,实现一套聊天室软件。服务器端记录客户端的地址,客户端发送消息后,服务器群发给各个客户端软件,服务器也可以自己发送通知给所有客户端。  ......
  • 【网络】UDP回显服务器和客户端的构造,以及连接流程
    回显服务器(EchoServer)最简单的客户端服务器程序,不涉及到业务流程,只是对与API的用法做演示客户端发送什么样的请求,服务器就返回什么样的响应,没有任何业务逻辑,没有进行任何计算或者处理0.构造方法网络编程必须要使用网卡,就需要用到Socket对象创建一个DatagramS......
  • STM8 窗口看门狗实验:保护嵌入式系统的可靠性与稳定性
    嵌入式系统在各个领域中扮演着重要的角色,因此确保其可靠性和稳定性至关重要,本文将介绍如何利用STM8微控制器的窗口看门狗(IWDG)功能,来保护嵌入式系统的运行,我们还将提供相应的源代码示例,以帮助读者理解和实施这一功能。看门狗定时器是一种硬件模块,用于监控系统在预定时间内是否......
  • 第六章 网络互连与互联网(五):TCP 和 UDP 协议
    五、TCP和UDP协议在TCP/IP协议簇中有两个传输协议,即传输控制协议(TCP)和用户数据报协议(UDP)。TCP是面向连接的,而UDP是无连接的。1、TCP服务(1)TCP协议提供面向连接的、可靠的传输服务,适用于各种可靠的或不可靠的网络。(2)TCP用户送来的是字节流形式的数据,这些数据缓存......
  • Python 通过UDP传输超过64k的信息
    在UDP中,单个数据包的最大尺寸通常受到网络层的限制,这通常被称为最大传输单元(MTU)。在以太网环境中,标准的MTU大小通常为1500字节。尽管有些网络环境可能支持更大的数据包,但是UDP数据包的理论最大限制是65535字节(64KB),这是由于UDP头部的16位长度字段决定的。然而,如果你需要发送超过这......
  • udp和arp之间的交互作用
    udp和arp之间的交互作用arp-a验证arp告诉缓存是空的sock-u-i-nl-w8192svr4discard1.在第一个arp应答返回以前,总共产生了6个arp请求。2.在接收到第一个arp应答时(第7行),只发送最后一个数据报片(第9行)3.在大多数的现实中,在等待一个arp应答时,只将最后一个报文发送给特定目标......
  • udp介绍
    1.udp介绍udp是一个简单的面向数据报的运输层协议,进程的每个输出操作都正好产生一个udp数据报,并组装成一份待发送的ip数据包,这与面向流字符的协议不同,如tcp,应用程序产生的全体数据与真正发送的单个ip数据报可能没有什么联系。udp不提供可靠性:它把应用程序传给ip层的数据发送出......