UDP

以及TCP是什么。我们知道传输层中有TCP和UDP两种网络协议,这节就讲UDP是什么。

Internet协议集支持一个无连接的传输协议,该协议称为用户数据报协议(UDP,User Datagram Protocol)。UDP为应用程序提供了一种无需建立连接就可以发送封装的IP数据包的方法。RFC 768描述了UDP。

UDP API

图片来自网络

TCP与UDP的不同

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

  • TCP是面向连接的传输控制协议,而UDP提供了无连接的数据报服务;
  • TCP 具有高可靠性,确保传输数据的正确性,不出现丢失或乱序;UDP 在传输数据前不建立连接,不对数据报进行检查与修改,无须等待对方的应答,所以会出现分组丢失、重复、乱序,应用程序需要负责传输可靠性方面的所有工作;
  • UDP具有较好的实时性,工作效率较TCP协议高;
  • UDP段结构比 TCP的段结构简单,因此网络开销也小。
  • TCP协议可以保证接收端毫无差错地接收到发送端发出的字节流,为应用程序提供可靠的通信服务。对可靠性要求高的通信系统往往使用TCP传输数据。

KCP

什么是KCP

TCP优缺点:

我们知道TCP有超时重传和滑动窗口机制提供了TCP的可靠性和流控特性,滑动窗口和拥塞控制可以使得TCP做到流量控制。但是TCP协议是从大局上考虑的,大公无私,经常牺牲自己速度来减少网络拥塞。且TCP高度自治,很多参数没法配置。

UDP优缺点:

UDP协议简单,所以它更快。但是,UDP毕竟是不可靠的,应用层收到的数据可能是缺失、乱序的。

不管是端游还是手游,对于延时的要求都同样重要,因为延时直接关系到游戏的体验。并且不同的游戏对延时的忍受程度不尽相同,例如:FPS延时超过了100ms体验就不怎么好了,Moba在这种程度却觉得很好,MMO甚至到了200ms还可以愉快玩耍,但不管什么游戏,延时越低,体验就越好。

TCP的特性导致网络在不好的时候,延迟会变的很高。UDP的延迟很低,但是不可靠,乱序。

KCP是一种网络传输协议(A Fast and Reliable ARQ Protocol),纯算法实现,并不负责底层协议(如UDP)的收发,需要使用者自己定义下层数据包的发送方式,以callback的方式提供给KCP。连时钟都需要外部传递进来,内部不会有任何一次系统调用。本文传输协议只考虑UDP的情况。

KCP基于UDP协议,在尽可能保留UDP快的前提下,借鉴了TCP的机制来保证可靠。KCP相比TCP浪费了10%~20%的带宽代价,换取了平均延迟降低30%~40%,且最大延迟降低三倍的传输效果。

KCP是自私的,它只顾自己的传输效率,从不管整个网络的拥塞情况。举个例子,TCP检测到丢包的时候,首先想到的是网络拥塞了,要放慢自己的速度别让网络更糟,而KCP想到的赶紧重传别耽误事。

对比KCP和TCP:

  • KCP尽可能保留UDP快的特点下,保证可靠;TCP保证网络绝对的可靠,所以设计复杂,速度慢。
  • KCP是为流速设计的,重点是降低应用网络延迟;TCP是为流量设计的,可以充分利用带宽。
  • KCP是应用层协议,底层是UDP;TCP是传输层协议。

用个比喻来形容就是TCP是条流速较慢但是流量很大的运河,而KCP是条水流湍急的小激流。

KCP协议只有 ikcp.h, ikcp.c两个源文件,可以方便的集成到用户自己的协议栈中。

图片来自网络:

KCP工作流程

KCP的工作流程如下图所示:

 

图中的send_queue是发送队列,send_buf是发送缓冲区,rcv_buf是接收缓冲区,rcv_queue是接收队列。队列和缓冲区的实现都是双向循环列表,通过宏定义来实现。queue和buff的结点就是一个kcp报文。

  • ikcp_update:循环定时调用

发送工作流程:

  • ikcp_send: 将用户待发送的数据填充成KCP报文段,放入snd_queue。
  • ikcp_flush: 调用输出回调将发送缓冲区中的数据发送出去。Ikcp_send不会将数据直接发送出去,只会将报文段放入snd_queue,等待下一次ikcp_update来调用ikcp_flush,将数据从snd_queue中移动到snd_buf后再发送数据。具体哪些报文可以发送,需要通过滑动窗口来控制,避免一次性发送太多的数据导致拥塞。

通过发送工作流程,可以发现发送数据需要等待flush,有发送延迟问题。普遍的解决方案是send之后立即调用一次update,但这样做会带来较大的系统开销。

接收工作流程:

  • ikcp_input: 接收传输层数据,包括用户数据报文段以及ACK报文;接收完后放入rcv_buff,等到接收完一段完整有序的报文之后,才会移动到rcv_queue中供接收方处理。
  • ikcp_recv:从rcv_queue中读取数据,触发接收逻辑。

可靠性

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

ARQ协议有两种模式:

  • ACK模式(停等ARQ协议),同步请求响应模式,基于超时重传保证可靠。
  • UNA模式(连续ARQ协议),可以连续发送多个分组,而不必每发完一个分组就停下来等待对方确认,TCP就是如此。连续ARQ协议不会响应每个数据段,而是仅仅响应编号最大的这个数据段,表示之前的数据都收到了。

KCP的ARQ:光用UNA如果丢包将导致全部重传,光用ACK则丢失成本太高。以往协议都是二选其一,而KCP有单独ACK包,且数据包和ACK包都带UNA信息,有效降低ACK丢失成本。

确认与重传

KCP 确认重传实现机制:ACK+UNA;超时重传+快速重传;选择重传

  • 在TCP中,有超时重传机制,KCP中设置快速模式,可控制RTO成*1.5
  • 由于KCP的ARQ模式是ACK+UNA,所以KCP除了超时重传还有选择重传机制
  • 选择重传:返回的ACK中包含rcv_nxt和sn。rcv_nxt代表收到的所有连续的包,sn代表哪些不连续的包收到了,那么根据这两个参数可以计算出来没有收到的包的序号。发送方接收到接收方发过来的数据时,首先解析rcv_nxt,把所有小于rcv_nxt序号的包从发送缓存队列中移除。然后再解析sn(大于rcv_nxt),遍历发送缓存队列,找到所有序号小于sn的包,就是被选择重传的包。
  • 快速重传:根据我们设置的快速重传的门限,对每个分片维护一个快速重传的计数。每收到一个ACK解析sn后找到了一个分片,就把该分片的快速重传的计数加一。如果该计数达到了快速重传门限,那么就认为该分片已经丢失,可以触发快速重传。
  • KCP在发生快速重传且数据包乱序时,采用的是TCP快恢复的策略。控制窗口调整为已经发送没有接收到ack的数据包数目的一半+resent。

流量控制

流量控制有两机制:滑动窗口和拥塞控制。

滑动窗口的接收方告知发送方自己可以接收缓冲区的大小,通常与连续ARQ协议配合使用。滑动窗口就是TCP头部的16位大小窗口字段,而UDP没有这个字段。

拥塞控制的关键是四个算法:慢开始、拥塞避免、快速重传、快速恢复。

KCP滑动窗口:

滑动窗口默认大小为32,即可以接收最大为32*MTU=43.75kB。KCP采用update的方式,更新间隔为10ms,那么KCP限定了你最大传输速率为4375kB/s,在高网速传输大内容的情况下需要调用ikcp_wndsize调整接收与发送窗口。建议从应用侧更好的控制发送流量与网络速度持平,避免缓存堆积延迟。

KCP拥塞控制:

KCP的拥塞控制可以关闭。KCP的优势在于可以完全关闭拥塞控制,非常自私的进行发送。KCP采用的拥塞控制策略为TCP最古老的策略,无任何优势。完全关闭拥塞控制,也不是一个最优策略,它全是会造成更为拥堵的情况。

KCP VS TCP

  • TCP的RTO是直接翻倍,但是试验测试发现RTO*=1.5比RTO*=2要好,所以KCP选择了RTO*=1.5,提高了丢包时的传输速度。
  • 快速重传:发送端发送了1,2,3,4,5几个包,然后收到远端的ACK: 1, 3, 4, 5,当收到ACK3时,KCP知道2被跳过1次,收到ACK4时,知道2被跳过了2次,此时可以认为2号丢失,不用等超时,直接重传2号包,大大改善了丢包时的传输速度。
  • 延迟ACK vs 非延迟ACK :TCP为了充分利用带宽,延迟发送ACK(NODELAY都没用),这样超时计算会算出较大RTT时间,延长了丢包时的判断过程。KCP的ACK是否延迟发送可以调节。
  • UNA vs ACK+UNA :TCP使用的UNA模式,有丢包全部重传问题;KCP有单独ACK,且数据包和ACK包都带UNA信息,有效降低ACK丢失成本。
  • TCP丢包时会全部重传从丢的那个包开始以后的数据;由于KCP使用了ACK+UNA模式,KCP是选择性重传,只重传真正丢失的数据包。
  • 非退让流控:KCP正常模式同TCP一样使用公平退让法则,即发送窗口大小由:发送缓存大小、接收端剩余接收缓存大小、丢包退让及慢启动这四要素决定。但传送及时性要求很高的小数据时,可选择通过配置跳过后两步,仅用前两项来控制发送频率。以牺牲部分公平性及带宽利用率之代价,换取了开着BT都能流畅传输的效果。(KCP非退让流控可以理解为对及时性要求很高的小数据只考虑滑动窗口,看你发送窗口和接收窗口是否允许我传输

其他

  • 当用户数据很大,大于一个UDP包能承担的范围时(大于mss),KCP会将用户数据分片存储在多个KCP包中。因此每个KCP包称为一个分片。
  • 用户控制:拥塞控制可以取消、ACK回复可以设置成无延迟ACK回复、KCP的RTO可以控制成*1.5
  • KCP只是一套基于无连接的数据报文之上的连接和拥塞控制协议,对底层无连接的数据报文没有具体的限制,可以基于UDP,也可以基于伪造的 TCP/ICMP等,也可以基于某些特殊环境的非internet网络(比如各种现场通信总线)

UDP与KCP详解的更多相关文章

  1. 以太网帧格式、IP数据报格式、TCP段格式+UDP段格式 详解

    转载:http://www.cnblogs.com/lifan3a/articles/6649970.html 以太网帧格式.IP数据报格式.TCP段格式+UDP段格式 详解   1.ISO开放系统有 ...

  2. 计算机网络(六),UDP报文段详解

    目录 1.UDP作用 2.UDP报文段详解 六.UDP报文段详解 1.UDP作用 (1)面向非连接 (2)不维护连接状态,支持同时向多个客户端传送相同的消息 (3)报文段报头只有8个字节,格外开销较小 ...

  3. TCP、UDP和HTTP详解

    http:是用于www浏览的一个协议.tcp:是机器之间建立连接用的到的一个协议. 1.TCP/IP是个协议组,可分为三个层次:网络层.传输层和应用层.在网络层有IP协议.ICMP协议.ARP协议.R ...

  4. 网络编程UDP、TCP详解

    网络编程   网络编程主要用于解决计算机与计算机(手机.平板-)之间的数据传输问题. 1.InetAddress(IP类)   方法: 方法 描述 getLocalHost() 获取本机的IP地址对象 ...

  5. 《TCP/IP详解卷1:协议》第11章 UDP:用户数据报协议-读书笔记

    章节回顾: <TCP/IP详解卷1:协议>第1章 概述-读书笔记 <TCP/IP详解卷1:协议>第2章 链路层-读书笔记 <TCP/IP详解卷1:协议>第3章 IP ...

  6. TCP/UDP详解

    转载:http://www.cnblogs.com/visily/archive/2013/03/15/2961190.html, 作者:望梅止渴 相关: HTTP协议详解  深入理解HTTP协议 T ...

  7. ip头、tcp头、udp头详解及定义,结合Wireshark抓包看实际情况

    公司的同事们在分析网页加载慢的问题,忽然使用到了Wireshark工具,我就像发现新大陆一样好奇,赶紧看了看,顺便复习了一下相关协议.上学时学的忘的差不多了,汗颜啊! 报文封装整体结构 mac帧头定义 ...

  8. TCP/IP、UDP、HTTP、SOCKET详解

    文章大纲 网络OSI七层及各层作用 TCP与UDP基本介绍 TCP连接过程详解 SOCKET原理与连接详解     一.网络OSI七层及各层作用   应用层:文件传输,电子邮件,文件服务,虚拟终端 T ...

  9. TCP、UDP详解与抓包工具使用

    参考:https://www.cnblogs.com/HPAHPA/p/7737641.html TCP.UDP详解 1.传输层存在的必要性 由于网络层的分组传输是不可靠的,无法了解数据到达终点的时间 ...

  10. 【TCP/IP详解 卷一:协议】第十一章 UDP 用户数据报协议

    11.1 引言 UDP 是一个简单的 面向数据报 的运输层协议:进程的每个 输出操作 都正好产生一个 UDP数据报,并且组装成一份待发送的IP数据报. 这与 TCP 不一样,它是 面向流字符 的协议, ...

随机推荐

  1. 解密IP分片与重组:数据传输中的关键技术

    引言 在上一章节中,我们详细讨论了IP的分类和无分类原则的原理以及其在网络通信中的应用.IP分片与重组是在数据包传输过程中起到关键作用的机制.当数据包的大小超过网络链路的MTU(最大传输单元)限制时, ...

  2. java_方法使用细节

    java_方法使用细节 1.一个方法想要返回多个值 思考?一个方法如何返回多个值 返回数组 class AA{ public int[] getSumAndSub(int n1, int n2){ / ...

  3. c语言代码练习9

    \\判断1000-2000之间的闰年有哪些,有几个 #define _CRT_SECURE_NO_WARNINGS 1#include <stdio.h> int main(){ //判断 ...

  4. 10.4 认识Capstone反汇编引擎

    Capstone 是一款开源的反汇编框架,目前该引擎支持的CPU架构包括x86.x64.ARM.MIPS.POWERPC.SPARC等,Capstone 的特点是快速.轻量级.易于使用,它可以良好地处 ...

  5. 一套基于 .NET Core 开发的支付SDK集 - paylink

    前言 在我们的日常工作开发中对接一些第三方支付是比较常见的,如最常见的就是支付宝.微信支付的对接.今天给大家推荐一个基于.NET Core开发的支付SDK集:paylink,它极大简化了API调用及通 ...

  6. VS Code代码提示( AcWing算法模板,C++实现)

    算法模板提取于AcWing上的代码提示 作者:yxc 链接:https://www.acwing.com/file_system/file/content/whole/index/content/21 ...

  7. 一场3天前的cf

    啊 这次的cf其实水的(指前4题) 题面就不给了awaT1其实就是一个贪心,其实手模一下就好了.可以发现,先让小的那个变大,然后在后面一直让小的加上大的统计一下次数就是答案了.因为如果是这样算的话,两 ...

  8. CF755C

    题目简化和分析: 这题不用说怎么分析了吧,这一看就是个并查集求连通分量个数的经典模板. 我们需要将 \(i\) 和 \(p_i\) 进行合并. 遍历每个 \(i\) 与 \(i+1\) 是否属于同一个 ...

  9. Util应用框架快速入门(5) - 权限入门

    本文将引导你运行Util权限管理模块,并对UI按钮和API操作进行访问控制. Util平台介绍 Util应用框架是一组类库,它们提供了有用的功能. 虽然Util配套代码生成器能够帮助你创建项目基架,但 ...

  10. 阿里发布AI编码助手:通义灵码,兼容 VS Code、IDEA等主流编程工具

    今天是阿里云栖大会的第一天,相信场外的瓜,大家都吃过了.这里就不说了,有兴趣可以看看这里:云栖大会变成相亲现场,最新招婿鄙视链来了... . 这里主要说说阿里还发布了一款AI编码助手,对于我们开发者来 ...