KCP协议浅析
概述
KCP协议结合了TCP和UDP协议的特点,是一个快速可靠的协议。
引述官方介绍:
KCP是一个快速可靠协议,能以比 TCP浪费10%-20%的带宽的代价,换取平均延迟降低 30%-40%,且最大延迟降低三倍的传输效果。纯算法实现,并不负责底层协议(如UDP)的收发,需要使用者自己定义下层数据的发送方式,以 callback的方式提供给 KCP。连时钟都需要外部传递进来,内部不会有任何一次系统调用。
TCP是为流量设计的(每秒内可以传输多少KB的数据),讲究的是充分利用带宽。而 KCP是为流速设计的(单个数据从一端发送到一端需要多少时间),以10%-20%带宽浪费的代价换取了比 TCP快30%-40%的传输速度。
传统的TCP/UDP协议见参考链接。
协议格式
| 4bit conv | 1bit cmd | 1bit frg | 2bit wnd |
| 4bit ts | 4bit sn |
| 4bit una | 4bit len |
| anybit 数据 |
- conv:会话序号,通信双方一致
- cmd:报文类型
- IKCP_CMD_ACK 确认
- IKCP_CMD_PUSH 数据推送
- IKCP_CMD_WASK 接收窗口查询大小
- IKCP_CMD_WINS 接收窗口大小告知
- wnd: 己方可用接收窗口大小,接收窗口大小 - 接收队列大小
- frg:包分片(数量)
- sn: 包分片序号
- ts: 时间戳,用于计算RTO和RTT
- una:待接收的序列号(确认号),表示该序列号之前的所有报文都收到了,可以删除
- len:用户数据长度
- 数据:用户数据
特点
RTO不翻倍
RTO(Retransmission-TimeOut)即重传超时时间,TCP和KCP是基于ARQ协议实现的可靠性,但TCP的超时计算是RTO2,而KCP的超时计算是RTO1.5,也就是说假如连续丢包3次,TCP是RTO8,而KCP则是RTO3.375,意味着可以更快地重新传输数据。
选择性重传
tcp 丢包时会全部重传从该包开始以后的数据,而 kcp 选择性重传,只重传真正丢失的数据包。
快速重传
收到fastresend(配置)个失序报文后,不等待超时,直接重传,减少丢包等待时间。
而TCP重传模式:
- 超时重传:超过规定的时间 RTO 则重传
- 快速重传:收到三个冗余ACK,不去等待 RTO ,直接重传
与TCP相同,都是通过累计确认实现的,发送端发送了1,2,3,4,5几个包,然后收到远端的ACK:1,3,4,5,当收到ACK = 3时,KCP知道2被跳过1次,收到ACK = 4时,知道2被跳过了2次,此时可以认为2号丢失,不用等超时,直接重传2号包,大大改善了丢包时的传输速度。
非延迟 ACK
停等ARQ协议

- A会为每个即将发送的数据编号,编号的目的是为了标识数据和给数据排序
- A发送完数据之后,会给这次发送的数据设置一个超时计时器
- B收到数据,将会返回一个确认,该确认也有自己的编号
- A收到确认,将删除副本且取消超时计时器,保留副本的原因是传输可能出错
- B收到错误的数据,或者数据在传输过程中出错,总之就是说B没有收到想要的数据
- A在超时计时器的设置时间内没有收到确认,此时重发数据
所以可靠的TCP有32位序列号和32位确认号,TCP和UDP都有16位校验和。
连续ARQ协议

连续ARQ协议不会响应每个数据段,而是仅仅响应编号最大的这个数据段,表示之前的数据都收到了,这个叫做UNA模式,而停等ARQ协议可以看作是ACK模式
ACK + UNA
ARQ (自动重传请求,Automatic Repeat-reQuest)模型响应有两种方式:
- UNA:此编号前所有包已收到
- ACK:该编号包已收到
只用 UNA 将导致全部重传,只用 ACK 则丢失成本太高,以往协议都是二选其一。而 kcp 协议中,除去单独的 ACK 包(精确)外,所有包都有 UNA 信息
非退让流控
KCP正常模式同TCP一样使用公平退让法则,即发送窗口大小由:发送缓存大小、接收端剩余接收缓存大小、丢包退让、慢启动这四要素决定,慢启动是在刚开始发送数据时让窗口缓慢扩张,退半避让是在网络拥堵时窗口大小减半,快重传是在网络恢复时及时给予响应,与之配合的就是快恢复。但传送及时性要求很高的小数据时,可选择仅用前两项来控制发送频率。以牺牲部分公平性及带宽利用率之代价,换取了流畅传输的效果。KCP 实时性好,但带宽利用率较低,因为:
- 非退让流控,不断尝试发送数据,有效包不多
- 每个包应答,占用一定的带宽
窗口协议中有两种:
- 拥塞窗口:防止过多的数据注入到网络中,这样可以使网络中的路由器 和链路不至于过载。
- 滑动窗口:接收方告知发送方自己可以接收缓冲区的大小,通常与连续ARQ协议配合使用。
结构

大概流程如图示,若是想深入探索底层实现,请参考源码或者参考链接中的详解
参考链接
KCP协议浅析的更多相关文章
- Kcptun 是一个非常简单和快速的,基于KCP 协议的UDP 隧道,它可以将TCP 流转换为KCP+UDP 流
本博客曾经发布了通过 Finalspeed 加速 Shadowsocks 的教程,大家普遍反映能达到一个非常不错的速度.Finalspeed 虽好,就是内存占用稍高,不适合服务器内存本来就小的用户:而 ...
- 计算机网络通信TCP/IP协议浅析 网络发展简介(二)
本文对计算机网络通信的原理进行简单的介绍 首先从网络协议分层的概念进行介绍,然后对TCP.IP协议族进行了概念讲解,然后对操作系统关于通信抽象模型进行了简单介绍,最后简单描述了socket 分层的 ...
- Http协议浅析
目录 Http协议浅析 http协议简介 http协议特性 http请求协议与响应协议 请求协议 响应协议 响应状态码 请求URI定位资源 HTTP方法 GET:获取资源 POST:传输实体主体 PU ...
- kcp协议详解
kcp协议是传输层的一个具有可靠性的传输层ARQ协议.它的设计是为了解决在网络拥堵情况下tcp协议的网络速度慢的问题.kcp力求在保证可靠性的情况下提高传输速度.kcp协议的关注点主要在控制数据的可靠 ...
- 可靠UDP,KCP协议快在哪?
WeTest 导读 云真机已经支持手机端的画面投影.云真机实时操作,对延迟的要求比远程视频对话的要求更高(100ms以内).在无线网络下,如何更实时.更可靠的传输视频流就成了一个挑战.通过websoc ...
- protobuf 协议浅析
目录 Protobuf 协议浅析 1. Protobuf 介绍 1.1 Protobuf 基本概念 1.2 Protobuf 的优点 1.3 Protobuf, JSON, XML 的区别 2. Pr ...
- 【转载】远程桌面协议浅析(VNC/SPICE/RDP)
远程桌面协议浅析(VNC/SPICE/RDP) 2016年05月14日 01:27:06 wait_for_that_day5 阅读数:18317 标签: VNCRDPSPICE 更多 个人分类: 工 ...
- KCP协议:从TCP到UDP家族QUIC/KCP/ENET
行文前先安利下<再深谈TCP/IP三步握手&四步挥手原理及衍生问题-长文解剖IP >.<再谈UDP协议-浅入理解深度记忆> KCP协议科普 KCP是一个快速可靠协议,能 ...
- 远程桌面协议浅析(VNC/SPICE/RDP)
由于最近项目涉及到虚拟桌面,就花了点时间找了点资料看了一下,目前常用的协议有VNC/SPICE/RDP三种,就在这里做一个简单的介绍. 三种协议的对比 SPICE VNC RDP BIOS屏幕显示 能 ...
- CAN-FD协议浅析
引言 随着电子.半导体.通讯等行业的快速发展,汽车电子智能化的诉求也越来越强,消费者希望驾驶动力性.舒适性.经济性以及娱乐性更强的汽车.汽车制造商为了提高产品竞争力,将越来越多的电子控制系统加入到汽车 ...
随机推荐
- 给定两个字符串,均只包含英文字母,需区分大小写,一个是源字符串SS(长度<1000), 另一个是目标字符串TS(长度<1000),请问能否通过删除SS中的字符(不改变顺序)将它变换成TS,如果可以输出“YES",不可以则输出“NO"。 输入说明:第一行为源字符串SS,第二行为目标字符串TS。
import java.util.Scanner;/* 给定两个字符串,均只包含英文字母,需区分大小写,一个是源字符串SS(长度<1000), 另一个是目标字符串TS(长度<1 ...
- React之一个组件的诞生
此处以input组件为例 input.js import React from 'react' class Input extends React.Component { // ps:使用static ...
- nodejs 配置国内镜像
npm config set registry https://registry.npm.taobao.org npm config set disturl https://npm.taobao.or ...
- 一键搭建dns
#!/bin/bash DOMAIN=wang.orgHOST=wwwHOST_IP=10.0.0.100LOCALHOST=`hostname -I | awk '{print $1}'` . /e ...
- Python爬虫之用Selenium做爬虫
我们在用python做爬虫的时候,除了直接用requests的架构,还有Scrapy.Selenium等方式可以使用,那么今天我们就来聊一聊使用Selenium如何实现爬虫. Selenium是什么? ...
- css cursor: url() 使用火狐浏览器问题,鼠标没有效果
在火狐浏览器问题使用cursor: url():鼠标没有效果,需要给使用标签添加一个height
- 基础篇:windows常用命令
1. windows常用系统命令 cd [进入目录] dir [列出当前目录文件] echo + 打印内容 [打印命令] echo 123 > 1.txt [打印内容到文本] type + 文件 ...
- python 循环 类型转换
- kubeadm搭建k8s
一.kubeadm 部署 K8S 集群架构 主机名 IP地址 安装组件 master(2C/4G,cpu核心数要求大于2) 192.168.160.20 docker.kubeadm.kubelet. ...
- Q:oracle锁表如何处理
解决ORA-00054资源正忙的问题 有时候在drop表或者其他对象的时候,会遇到ORA-00054:资源正忙,要求指定NOWAIT(中文字符集)或者ORA-00054: resource busy ...