UDP的可靠传输--KCP
一. 如何做到可靠传输
在总的理解的可靠传输我们通常首先会想到TCP,但其建立连接的过程以及一些其他方面过于复杂,我们是否能够通过修改UDP的内容,借用TCP的部分思想来做到可靠传输呢。
实现可靠传输主要使用的以下四个机制:
1
2
3
4
5
6
7
ACK机制:应答机制,我发送数据过去,对方有回应传回,保证数据可以到达对方。
重传机制 重传策略:在应答机制的基础上,在一个周期内进行检查是否受到应答,若没有应答就进行重传。那么这个周期该设为多大呢?这里就要用到RTT(往返时延)了。
序号机制与重排机制:在发送端发送数据包时的顺序是3,2,1;但在接受的时候接收到的顺序可能变为了2,3,1,那么此时就要重新排序这三个数据包。TCP中有这个重排机制,而UDP中没有。
窗口机制,流量控制与带宽有限 > 怎么处理先后顺序的问题? > 在UDP传输中,数据包通过路由后到达客户端的顺序可能有所区别,如何在客户端重新排列这个顺序是我们关键需要解决的问题。 # 二. UDP与TCP如何进行选择
UDP是面向报文的传输,什么叫面向报文,报文传输是指将发送的数据看作一个整体,但其发送的顺序没法保证。 而TCP是面向字节流的传输,这里既然提到流,就意味着其可以从中截断接受。
举个例子: 报文传输:sendto(hello),sendto(world)。这里再调用recvfrom则返回hello,再调用recvfrom则返回world,报文传接之间一一对应。 字节流传输:send(hello),send(world)。调用recv则返回helloworld,也可以指定一个一个字节接受。
ARQ(Automatic Repeat-Request)协议的三种模式
- 即停模式(stop and wait)ARQ:发送数据后等待接受到应答后再发送下一个数据;这种模式基本不用。
- 回退n帧(go-back-n)ARQ:在一个窗口内,若某一位置发生了丢包,那么从这个位置开始的后面所有都需要重新发送,如2号数据包丢失,则其后面的数据包都需进行重传。
- 选择重传ARQ:若2这个包没有应答,则选择性的重新传2这个包就行了。
什么是流量控制
举个简单的例子,我们从服务器发送数据时,网关通常有其限速,再G0,G1,G2带宽都为100M,这时服务器都以100M速率发送过来,但在G2分配给两个客户端的速率总和最多只有100M,这其中的发送方的速率与接受方的速率不相等,其实就可以降低发送方速率来进行一定的控制。
三. UDP如何可靠,KCP(Keep Connection Protocol)协议在哪些方面有优势
KCP其实就是以10%-20%带宽浪费的代价换取了比TCP快30%-40%的传输速度。
3.1 RTO翻倍与不翻倍:
TCP超时计算是RTO2,若连续丢3次包就变成RTO8了; 而KCP超时只用RTO*1.5,这样也提高了传输速率。
3.2 选择重传与全部重传:
TCP丢包会从丢包处往后全部重传; 而KCP只重传丢失的那些数据包。
3.3 什么是快速重传:
举个例子:在发送端发送了1,2,3,4,5这几个包之后,远端收到ACK1,3,4,5,收到ACK3时,跳过一次,收到ACK4时,知道2被跳过两次,则认为2号包丢失,不用等超时时间,直接重传2号数据包,fastresend = 2。
3.4 延迟应答,非延迟应答与UNA:
TCP为了充分利用带宽,会延迟发送ACK,这样超时计算会算出较大的RTT时间,而KCP则可以自主调节是否延迟发送。UNA则表示 此编号之前的所有包都已收到,这时就可以删除前面的请求。
四. KCP的具体解析与应用
4.1 KCP的使用:
4.2 KCP流程图解释说明:
4.3 KCP配置模式:
- 工作模式: 这个接口 int ikcp_nodelay(ikcpcb *kcp, int nodelay, int interval, int resend, int nc)
- 最大窗口: int ikcp_wndsize(ikcpcb *kcp, int sndwnd, int rcvwnd); 设置最大发送窗口和最大接受窗口的大小,默认为32,单位为包。
- 最大传输单元: int ikcp_setmtu(ikcpcb *kcp, int mtu); kcp协议并不负责探测MTU,默认mtu是1400字节。
- 最小RTO: kcp->rx_minrto = 10;










