什么是KCP

KCP是一种网络传输协议(A Fast and Reliable ARQ Protocol),可以视它为TCP的代替品,但是它运行于用户空间,它不管底层的发送与接收,只是个纯算法实现可靠传输,它的特点是牺牲带宽来降低延迟。因为TCP协议的大公无私,经常牺牲自己速度来减少网络拥塞,它是从大局上考虑的。而KCP是自私的,它只顾自己的传输效率,从不管整个网络的拥塞情况。举个例子,TCP检测到丢包的时候,首先想到的是网络拥塞了,要放慢自己的速度别让网络更糟,而KCP想到的赶紧重传别耽误事。

TCP的特点是可靠传输(累积确认、超时重传、选择确认)、流量控制(滑动窗口)、拥塞控制(慢开始、拥塞避免、快重传、快恢复)、面向连接。KCP对这些参数基本都可配,也没用建立/关闭连接的过程。

其实KCP并不神秘,因为TCP的高度自治(很多东西都不可配),满足不了如今各种速度需求。而KCP就是基于UDP协议,再将一些TCP经典的机制移植过来,变成参数可配。在这种

怎么使用

KCP只有两个文件,分别是ikcp.cikcp.h,代码行数1300左右。使用KCP和使用TCP有些不同,所以上手之前需要先了解下KCP如何使用,需要时间成本。

第一步,就是创建一个kcp实例,相当于一个句柄。

ikcpcb* ikcp_create(IUINT32 conv, void *user)

第二步,设置发送数据的接口,底层用哪种socket都没问题,只要能把数据发送出去,建议使用UDP,比较简单。

int output(const char *buf, int len, ikcpcb *kcp, void *user)

第三步,更新KCP状态。KCP运行于用户空间,所以需要手动去更新每个实例的状态,其实主要就是检测哪些数据包该重传了。

void ikcp_update(ikcpcb *kcp, IUINT32 current)

第四步,发送数据。调用ikcp_send之后,KCP最后会使用上面设置的output函数来将发送数据(KCP自己并不关心如何发送数据)。

int ikcp_send(ikcpcb *kcp, const char *buffer, int len)

第五步,预接收数据。先手动预接收数据,然后再调用ikcp_input将裸数据交给KCP,这些数据有可能是KCP控制报文,并不是我们要的数据。

int ikcp_input(ikcpcb *kcp, const char *data, long size)

第六步,接收数据。此时收到的数据才是真正的数据,重组操作在调用ikcp_recv之前就完成了。

int ikcp_recv(ikcpcb *kcp, char *buffer, int len)

总体上还是容易理解的,以前我们是直接使用各种socket和对端通信,各种功能由自己控制。现在是在socket之上使用了一个中间件KCP,帮忙实现快速可靠传输功能。注意一下KCP有模式的区分,不同模式下的速度表现不一样,建议把参数配好之后再使用,否则使用的都是默认的参数。

快在哪里

  • 没用使用任何系统调用接口
  • 无需建立/关闭连接(就KCP本身来说)
  • 很多影响速度的参数都可配

使用场景

丢包率高的网络环境下KCP的优点才会显示出来。如果不丢包,那么TCP和KCP的效率不会差别很大,可能就是少了连接建立/关闭而已。一般来讲,在公网上传输的都可以使用,特别是对实时性要求较高的程序,如LOL。

有何缺点

  • 学习成本
  • 据说有些运营商对UDP有限制?

重新认识KCP的更多相关文章

  1. Kcptun 是一个非常简单和快速的,基于KCP 协议的UDP 隧道,它可以将TCP 流转换为KCP+UDP 流

    本博客曾经发布了通过 Finalspeed 加速 Shadowsocks 的教程,大家普遍反映能达到一个非常不错的速度.Finalspeed 虽好,就是内存占用稍高,不适合服务器内存本来就小的用户:而 ...

  2. Unity跨平台C/CPP动态库编译---可靠UDP网络库kcp基于CMake的各平台构建实践

    1.为什么需要动态库 a)提供原生代码(native code)的支持,也叫原生插件,但是我实践的是c/cpp跨平台动态库,这里不具体涉及安卓平台java库和ios平台的objectc库构建. b)某 ...

  3. KCP 传输协议

    作者:韦易笑链接:https://www.zhihu.com/question/36258781/answer/98944369来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明 ...

  4. 快速可靠网络传输协议 KCP(转)

    KCP 是一个快速可靠协议,能以比 TCP浪费10%-20%的带宽的代价,换取平均延迟降低30%-40%,且最大延迟降低三倍的传输效果.纯算法实现,并不负责底层协议(如UDP)的收发,需要使用者自己定 ...

  5. kcp协议详解

    kcp协议是传输层的一个具有可靠性的传输层ARQ协议.它的设计是为了解决在网络拥堵情况下tcp协议的网络速度慢的问题.kcp力求在保证可靠性的情况下提高传输速度.kcp协议的关注点主要在控制数据的可靠 ...

  6. 基于kcp,consul的service mesh实现

    名字kmesh 技术:proxy,kcp,consul proxy proxy分为前端和后端 前端代理服务层,包括外部的service 后端实现负债均衡 kcp kcp 基于udp,能够实现快速的传输 ...

  7. kcp流模式与消息模式对比

    kcp的流模式,和消息模式 流模式: 更高的网络利用率 更大的传输速度 解析数据相对更复杂 消息模式: 更小的网络利用率 更小的传输速度 解析数据相对更简单 消息模式的示意图 http://www.p ...

  8. kcp源码走读

    kcp协议与tcp协议类似,是一种ARQ协议.他的优点在于比tcp的延迟更小30%-40%,但相应的会牺牲一部分的带宽,大该比tcp多浪费10%~20%.tcp的设计目标是增大网络利用率,而kcp的设 ...

  9. 可靠UDP,KCP协议快在哪?

    WeTest 导读 云真机已经支持手机端的画面投影.云真机实时操作,对延迟的要求比远程视频对话的要求更高(100ms以内).在无线网络下,如何更实时.更可靠的传输视频流就成了一个挑战.通过websoc ...

随机推荐

  1. JAVA学习7:在Maven仓库中添加Oracle JDBC驱动

    由于Oracle授权问题,Maven3不提供Oracle JDBC driver,为了在Maven项目中应用Oracle JDBC driver,必须手动添加到本地仓库. 一.首先要得到Oracle ...

  2. 【Qt开发】01-第一个Qt程序Hello World!

    一:说在前头 我的第一份工作是做生产工具,当时用的MFC,IDE是VC6.0,现在想想真是古董级别,10年至今,微软也一直没有对MFC进行升级, 冥冥中感觉微软自己都放弃MFC了,市场上貌似MFC的岗 ...

  3. 【linux】在ubuntu中使用apt-get安装oracle jdk6

    在Ubuntu 12.04 LTS上安装JDK6本身并不复杂,只是目前较新版本的Ubuntu已经不支持直接通过apt-get安装了.因此,需要从Oracle官方网站下载安装包进行安装. 从Oracle ...

  4. poj 2405 Beavergnaw

    Beavergnaw Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6310   Accepted: 4158 Descri ...

  5. React.js 小书 Lesson25 - 实战分析:评论功能(四)

    作者:胡子大哈 原文链接:http://huziketang.com/books/react/lesson25 转载请注明出处,保留原文链接和作者信息. (本文未审核) 目前为止,第二阶段知识已经基本 ...

  6. 第一次尝试用ANT进行build

    虽然是软件工程专业学生,但很多东西都才刚刚接触,有些惭愧,但我相信“Later better than never”,所以我还是鼓励自己不断学习,以后尽量把自己新学会的东西记录下来,以此来督促自己的学 ...

  7. C#导入Excel|读取Excel方法

    OleDbConnection读取 /// <summary>       /// 返回Excel数据源       /// </summary>       /// < ...

  8. Java 基础(2)——编译运行 & 规范

    上节学到 Java 的编译与运行,我们已经学会了怎么去执行一个写好(假装我们已经会写了)的代码,这篇当然要试试手啦 O(∩_∩)O 哈哈~ 小试一下 新建一个 HelloAhanWhite.java ...

  9. Redis(MySQL和redis怎么分工合作的?)

    新手: redis也是服务器,主要部署在服务器上缓解服务器的压力,对于访问量交大的数据可以先缓存到redis,用户访问时直接访问redis,不用再直接访问数据库,缓解数据库的压力.mysql主要存储数 ...

  10. JavaEE之HttpServletResponse

    HttpServletResponse概述 我们在创建Servlet时会覆盖service()方法,或doGet()/doPost(),这些方法都有两个参数,一个为代表请求的request和代表响应r ...