GithubHelp home page GithubHelp logo

skywind3000 / kcp Goto Github PK

View Code? Open in Web Editor NEW
14.7K 610.0 2.5K 523 KB

:zap: KCP - A Fast and Reliable ARQ Protocol

License: MIT License

C 80.10% C++ 17.52% CMake 2.38%
kcp udp arq quic protocol srt rtc low-latency c ack

kcp's People

Contributors

alan-yly avatar andersc avatar b23r0 avatar chinsyo avatar egametang avatar enkiller avatar gyf19 avatar halx99 avatar homqyy avatar huahang avatar kumokyaku avatar l42111996 avatar liudf0716 avatar liuquanhao avatar losfair avatar miwarnec avatar monkeywithacupcake avatar myd7349 avatar oyyd avatar qxsoftware avatar realistikdash avatar shaoyuan1943 avatar shixiongfei avatar skywind3000 avatar szhnet avatar u2fsdgvkx1 avatar xboss avatar xtaci avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

kcp's Issues

关于feature里一些特性与tcp的比较

您好,咨询个问题

对于kcp feature里面列出的三个特性

  • 选择性重传 vs 全部重传
  • 快速重传
  • UNA vs ACK+UNA

对于开启了sack选项的tcp来说,这三点kcp是不是和tcp基本是一致的了?

怎么使用

测试代码test.cpp中有模拟网络 什么意思 ,这个不能像TCP那样用吗,建立连接,IP,端口,为啥测试代码中看不到这些

超过慢启动阈值后,拥塞窗口的增加算法

        if (kcp->cwnd < kcp->ssthresh) {
            kcp->cwnd++;
            kcp->incr += mss;
        }   else {
            if (kcp->incr < mss) kcp->incr = mss;
            kcp->incr += (mss * mss) / kcp->incr + (mss / 16);
            if ((kcp->cwnd + 1) * mss >= kcp->incr) {
                kcp->cwnd++;
            }
        }

超过慢启动阈值后,拥塞窗口的增加算法是基于什么原理?要达到什么效果呢?能不能详细讲一讲。谢谢

Do you accept donate?

Do you accept donate?

this is amazing protocol. like it very much

Do you accept donate?

ICONTAINEROF 宏定义的疑惑

大神您好!我研读您的 kcp 协议代码,发现一处地方不太明白,具体是 ikcp.h 的 156~157 行。如下:

#define ICONTAINEROF(ptr, type, member) ( \
	(type*)( ((char*)((type*)ptr)) - IOFFSETOF(type, member)) )

这里 ptr 是指向 member 的指针,而 type 是包含 member 成员的父结构类型,所以 (char*)((type*)ptr) 这个强制转换为 type* 的过程感觉有点儿奇怪,感觉有点儿多余。不知是否有什么特殊的技巧还是纯粹多写了一个强制转换?

test.cpp 内存问题请教

@skywind3000 我们考察了其他类似的项目,这个项目最为简洁,感谢!

vs2015 本身有个内存快照的功能,用来查找内存泄露.
我跑了下test.cpp, 仅在147 行将 if (next > 1000) break; 改为 if (next > 100000) break;

然后抓取了两个时间点的内存快照信息,发现有大量68字节大小的内存未释放.

总览
image

堆栈:
image

是不是有什么需要注意的地方? 谢谢!

_itimediff 的定义是有意写成这样的?

当 later - earlier > 0x7FFFFFFF 时,_itimediff 会返回一个负值,而实际上 later 是大于 earlier 的。

比如 _itimediff(0xFFFFFFFF, 1)

static inline long _itimediff(IUINT32 later, IUINT32 earlier) 
{
    return ((IINT32)(later - earlier));
}

ikcp_encode32u的字节序的转换为何没成功?

/* encode 32 bits unsigned int (lsb) */
static inline char *ikcp_encode32u(char *p, IUINT32 l)
{
#if IWORDS_BIG_ENDIAN
(unsigned char)(p + 0) = (unsigned char)((l >> 0) & 0xff);
(unsigned char)(p + 1) = (unsigned char)((l >> 8) & 0xff);
(unsigned char)(p + 2) = (unsigned char)((l >> 16) & 0xff);
(unsigned char)(p + 3) = (unsigned char)((l >> 24) & 0xff);
#else
(IUINT32)p = l;
#endif
p += 4;
return p;
}

加上IWORDS_BIG_ENDIAN宏后,应该将p前4字节做字节序转换,但经测发现没转成功。

包过大问题

如果一个包大小超过接收窗口大小,而窗口大小设置的值比255小,会出现一直无法接收的情况。因为部分数据包已经塞满了接收窗口,fr为0的包无法收到。这个问题怎么解决?

优化延迟,"延迟"的概念? RTT是网络链路固有属性

作者对延迟的定义是否存在歧义?
RTT,是网络链路的固有属性,传播时延是不可优化的,因为光速就那么点,链路长度除以光速,延迟是算的出来的。
“单个数据包从一端发送到一端需要多少时间”,不考虑协议栈,单纯算两端网卡发包和收包的时间间隔,是delay,是固有链路属性,受制于链路和队列。两端链路对称的情况下,是RTT/2.

作者对延迟的定义是?

做了 Node.js 扩展,希望能放置到【相关应用】中,还有关于版权协议的问题

Hi

感谢你贡献的 kcp 开源项目,我封装了 Node.js 扩展,项目地址在

https://github.com/leenjewel/node-kcp

希望能放置在 kcp 项目的 README 的【相关应用】列表中

最后,我看到你对项目使用了 GPL v2 协议,我使用了 Apache v2.0 协议,是有冲突的,考虑到 GPL 协议有些过于“强硬” ,是否能考虑更换可以兼容 Apache v2.0 的协议?

祝你愉快~

kcp 可以在手机端使用吗?

kcp 可以在手机端使用吗? 不知道大神有没有在uniy3d 项目集成过kcp? 如果可以的话, 最好可以来一个例子,谢谢

RealTime PVP 有时候需要的是单MTU数据大小内最大序列号数据包有效

RealTime PVP 有时候需要的是单MTU数据大小内最大序列号数据包有效

例如玩家的位置,玩家可能发送了1,2,3,4,5,6一共6次位置。
而另一个玩家可能只收取到了1,3,5,6。当收到3的时候,因为比1大,因此3可以直接拿来使用,当2后来抵达后,会被忽略掉。客户端只关心刚收到的数据包的序号大于上一次数据包收到的序号。

因此在这种情况下,并不要求重发。
请问KCP能够通过参数调整实现这种模式吗?

我认为其在LAN应用场景的通讯意义远大于传统CS应用场景

在大公司里都有一套自己的底层通讯框架,比如腾讯的Apollo。
如果想做独立开发者,才会考虑使用KCP。但是独立开发者的技能往往侧重于前端开发,对于怎么管理连接,保持连接等经验是欠缺的,而且项目本身也用不上。所以,独立开发者往往适合使用UDP的方式通讯。
我看到Github上没有对KCP进行UDP化的封装,就着手弄了一个:KCPSocket。
你可以像使用UdpSocket一样使用KCP,真正达到像UDP一样方便,又像TCP一样可靠。

https://github.com/slicol/KCP-Socket

KCP和TCP的比较

我尝试了一把KCP,测试KCP和TCP的延时情况,测试方法和自带的测试程序相似:

每20ms发送一个1k的数据包,发送1000次,统计数据来回的最大延时和平均延时
KCP配置为快速模式,TCP和KCP服务器都为简单的echo服务,每1ms调用一次updata()

**1.**在内网环境下,KCP完全没有优势,TCP的平均延时小于1ms,kcp的延时约9ms

**2.**在外网(有线)环境下,平均延时TCP(7ms),KCP(15ms)依然没有优势,只是KCP(50ms)的最大延时小于TCP(秒级),且没有大的抖动,TCP有时会出现秒级的延时,而KCP很少出现这种情况

**3.**在4G环境下(移动4G),和外网环境下测试结果相似,KCP(65ms)的平均延时高于TCP(55ms),同样的,TCP(1秒左右)比KCP(350ms)有更大的抖动

**4.**我现在应用场景是客户端(手机)一发一收(需要收到回应才发下一个包),约30次小于1k的数据交互,其中有几次交互需要延时小于90ms,目前用TCP有失败的概率,想用KCP改善(降低整个流程的交互时间,提高用户体验,减少失败概率)

**5.**从结果上来看,KCP显得很鸡肋,从移动应用的角度看,他花费了更多的流量,并没有换取延时的降低(指平均延时)

**6.**可能是我测试程序不能体现出KCP的优势,我想知道您是 怎么测试得出 “能以比 TCP浪费10%-20%的带宽的代价,换取平均延迟降低 30%-40%” ,或者源码的目录里能否把这份测试程序公开,这样我也能比较信服的接受

**7.**如果只是做收发数据耗时的测试(10M数据测试,每个包1k),TCP是一发一收数据的统计和,而UDP并非一发一收,单个数据包来回的延时都是秒级的,但总的耗时是低于TCP的,只有TCP的20%,但如果KCP也写成收到一个包才发送下一个包的话,两者并没有多少差距

写了很多,1是希望得到解答,2是希望楼主能把KCP的应用场景再明确一下

关于奇怪的参数产生的问题

kcp1:lkcp_wndsize(6400, 6400)
kcp1:lkcp_nodelay(1, 5, 2, 1)设置一样
sleep(0)设置为0,客户端连续发包2000个长度20,接收完时间为10ms tcp为14ms
可是cpu比较高,sleep改为1的话相当于10ms的休眠,然后结果就变的19000ms才接收完2000个包
这个差距有点大的离谱

描述有一丝歧义

如果永远不丢包那么 KCP和 TCP性能差不多,但网络会卡,造成卡的原因就是丢包和抖动。

这句话有歧义,对KCP不了解的人从字面看上去,“网络会卡”可能是KCP造成的。是不是可以表述成“ 如果网络永远不丢包不抖动,那么 KCP和 TCP性能差不多。”

ikcp_send 后 output 不调用

       kcp = ikcp_create(0x11223344, (__bridge void *)(self));

        // 而考虑到丢包重发,设置最大收发窗口为128
        ikcp_wndsize(kcp, 128, 128);


        kcp->output = udp_output;

        ikcp_nodelay(kcp, 1, 10, 2, 1);
        kcp->rx_minrto = 10;
        kcp->fastresend = 1;


int udp_output(const char * buf, int len, ikcpcb * kcp, void * user)
{
    UDPSocket * socket = (__bridge UDPSocket *)(user);

    [socket.udpSendSocket sendData:[NSData dataWithBytes:buf length:len] toHost:host port:port withTimeout:-1 tag:0];

    printf(" --- udp send");

    return 0;
}


//编码完成后发送数据
- (void)ikcpSendData:(NSData *)data
{
    ikcp_update(kcp, [NSDate date].timeIntervalSince1970);
    int a = ikcp_send(kcp, data.bytes, sizeof(data.bytes));
    NSLog(@" -- ikcp_send => %d",a);
}

使用哪种FEC最高效,请指点。

目前已知的FEC方案包括:
1、openfec.org
2、tahoe-lafs.org/trac/zfec
3、Reed Solomon

哪种FEC理论上最能优化传输效率、避免重传呢?还是有我不知道的更好方案?还是哪两种结合使用?请您指点。

ikcp_recv 一直返回 -1

不知道是什么情况,在收到第一个正确的包后,接下来的包 一直返回-1.
是我发的太频繁了么?

针对ikcp_update的理解

不知道我理解的对不对哈, 客户端和服务端必须周期性的调用ikcp_update,来处理收发数据,如果不调用,就不会发送数据, 也就是说我必须开一个线程来调用ikcp_update,

还有个问题 对于实时性要求高,,数据包比较大,比如说视频流,,如何设置参数最优呢~

联系方式

有没有作者留下联系方式,有问题想请教

ikcp_send 后 output 不调用

       kcp = ikcp_create(0x11223344, (__bridge void *)(self));

        // 而考虑到丢包重发,设置最大收发窗口为128
        ikcp_wndsize(kcp, 128, 128);


        kcp->output = udp_output;

        ikcp_nodelay(kcp, 1, 10, 2, 1);
        kcp->rx_minrto = 10;
        kcp->fastresend = 1;


int udp_output(const char * buf, int len, ikcpcb * kcp, void * user)
{
    UDPSocket * socket = (__bridge UDPSocket *)(user);

    [socket.udpSendSocket sendData:[NSData dataWithBytes:buf length:len] toHost:host port:port withTimeout:-1 tag:0];

    printf(" --- udp send");

    return 0;
}


//编码完成后发送数据
- (void)ikcpSendData:(NSData *)data
{
    ikcp_update(kcp, [NSDate date].timeIntervalSince1970);
    int a = ikcp_send(kcp, data.bytes, sizeof(data.bytes));
    NSLog(@" -- ikcp_send => %d",a);
}

编码完成后调用 ikcp_send ,返回值是0, 但是 udp_output 方法并没有被调用, 我看了下 ikcp_send 方法的代码,没有找到哪里会调用 kcpouput 方法。

iqueue_del空指针异常

1052a420-bfc3-412a-b35c-f105c2e53370

应用在iOS上,这个地方偶有crash,观察那时候node的prev和next都是NULL,这么说IQUEUE_DEL的宏是不是应该加上空指针判断?

TCP转UDP保持长连接通信,请教KCP的参数设置问题

我在使用KCP做一个通信转换TCP-UDP-TCP的项目。我们的服务是基于TCP长连接的,但通常两端是异地的广域网,无法得到长时间稳定的TCP连接(例如难以超过24小时不断线),所以打算设计用UDP来完成中间通讯,两段分别对TCP进行转换为UDP。

流量是持续的、稳定的,峰值大约会有5Mbps,谷值大约500Kbps。ping延时范围大约是30ms ~ 100ms之间,取决于所在地域。

通讯中,数据的实时性是第一考虑要素。

Demo代码库是:https://github.com/btccom/BtcTunnel 。使用libevent作为事件通讯库。

想请教的问题是:

  • 对于这样的场景,ikcp_wndsize() / ikcp_nodelay() 如何设置会比较高效?
  • 不知 ikcp_update() 的调用方式是否正确?目前是:

还有一个现象是,当测试跨国(中美,丢包率5%15%,ping延时150ms250ms)通信的时候,数K的数据可以工作,然后数百K则无法正常工作,现象是 ikcp_recv() 先返回 –1, 然后数个 –2,然后就一直返回 –3 不知道是什么原因导致的?

Sending redundant data for lower latency on packet loss

This method is described well here http://gafferongames.com/building-a-game-network-protocol/reliable-ordered-messages/ .

In short, for example,

P1 == msg1 + msg2 + msg3
P2 == msg2 + msg3 + msg4
P3 == msg3 + msg4 + msg5

Then even if P2 is lost, msg4 can be recovered immediately by P3. This effectively multiples total data transmission size so it can't be for everything, but for sending small data periodically, it is a really effective method.

请问KCP中是否使用了冗余校验?

TCP中使用了冗余校验,可以减少重传,而KCP的文档中貌似没有提及任何冗余校验机制,那我就估计KCP没有使用冗余校验。如果确实没有使用,那么请问这是为什么?谢谢!

Any idea for Obfuscate ?

Any idea for Obfuscate ?
We think about to using KCP , but need more security (less resource usage, no much more cpu and memory usage)

kcp的cwnd控制

kcp的cwnd控制为:
慢启动过程:
每收到一批数据,cwnd++
非慢启动过程:
每收到一批数据,cwnd+=1/cwnd+1/16
丢包:
cwnd/=2
请问理解是否正确?

谁有例子

谁有例子 ,简单的能发能收就行
自己写的,速度上不来 ,两台机器 就几百K的速度
并且传时间长了 ,程序还崩溃了

关于WIKI中UDP连接不上的问题

在阅读WIKI(Cooperate With Tcp Server)的时候,文中写道,国内网络比较特殊,会存在有些UDP连接不上的情况。请教一下,在那些地区,或者哪些情况下,UDP会连接不上,存在这种问题的网络覆盖范围大吗?

memory leak

Hi, i have ran the asio_kcp in centos. But i found there is memory leak from server_lib. Do you know what may cause this... thanks!

I found ikcp_segment_new is called more times than ikcp_segment_delete! And i used free to see the mem status as follows...


[root@ ~]# free
total used free shared buffers cached
Mem: 1922244 237748 1684496 0 12260 155564
-/+ buffers/cache: 69924 1852320
Swap: 0 0 0
[root@ ~]# free
total used free shared buffers cached
Mem: 1922244 238104 1684140 0 12268 155972
-/+ buffers/cache: 69864 1852380
Swap: 0 0 0
[root@ ~]# free
total used free shared buffers cached
Mem: 1922244 250132 1672112 0 12532 167364
-/+ buffers/cache: 70236 1852008
Swap: 0 0 0

延迟ACK vs 非延迟ACK

README里有一段 "TCP为了充分利用带宽,延迟发送ACK(NODELAY都没用)", 有个选项TCP_QUICKACK可以控制,但是需要每次recv之后调用,有代价。这里不知道怎么描述可以更准确,吹毛求疵了,哈

关于fec

KCP只负责重传,并未加纠错,是不是因为公网传输时fec效果很有限,所以没必要?我们cto说公网里fec作用不大,我不知道是不是这样,请教skywind。谢谢!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.