mirror of
https://github.com/skywind3000/kcp.git
synced 2026-08-20 06:33:29 +08:00
Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b1a7a2101d | ||
|
|
f4694f598d | ||
|
|
c102b9b7f5 | ||
|
|
37c1c01da1 | ||
|
|
9aed788c9d | ||
|
|
2e1bd4a2c1 | ||
|
|
1ca0b18a43 | ||
|
|
284a977276 | ||
|
|
fbd716b257 | ||
|
|
7346e366f1 | ||
|
|
31c2ae0529 | ||
|
|
e8fc1fb840 | ||
|
|
46eed3ef30 | ||
|
|
19459fa64d | ||
|
|
b6953419c9 | ||
|
|
fddd37687d | ||
|
|
b3607a6d7d | ||
|
|
8aded6f405 | ||
|
|
c2ffc0554f | ||
|
|
d29b83e72f |
@@ -182,12 +182,14 @@ Both the use and configuration of the protocol is straightforward, in most cases
|
||||
- [kcp-java](https://github.com/hkspirt/kcp-java):Implementation of Java version of KCP protocol.
|
||||
- [kcp-netty](https://github.com/szhnet/kcp-netty):Java implementation of KCP based on Netty.
|
||||
- [java-kcp](https://github.com/l42111996/java-Kcp): JAVA version KCP, based on netty implementation (including fec function)
|
||||
- [kcp.kt](https://github.com/jokelbaf/kcp.kt): A pure-Kotlin Multiplatform implementation of KCP. Supports JVM, Linux, Windows, macOS and iOS targets.
|
||||
- [csharp-kcp](https://github.com/l42111996/csharp-kcp): csharp version KCP, based on dotNetty implementation (including fec function)
|
||||
- [kcp-go](https://github.com/xtaci/kcp-go): High-security GO language implementation of kcp, including simple implementation of UDP session management, as a base library for subsequent development.
|
||||
- [kcp-csharp](https://github.com/limpo1989/kcp-csharp): The csharp migration of kcp, containing the session management, which can access the above kcp-go server.
|
||||
- [KcpTransport](https://github.com/Cysharp/KcpTransport): KcpTransport is built on top of KCP ported to Pure C#, with implementations of Syn Cookie handshake, connection management, Unreliable communication, and KeepAlive. In the future, encryption will also be supported.
|
||||
- [Kcp-CSharp](https://github.com/Molth/Kcp-CSharp): a pure C# KCP instance callback(delegate) wrapper for (Unity/Godot/.NET)
|
||||
- [kcp2k](https://github.com/vis2k/kcp2k/): Line-by-line translation to C#, with optional Server/Client on top.
|
||||
- [KcpSharpN](https://github.com/new1271/KcpSharpN): The csharp version of KCP, translated from the original C code, includes a simple wrapper of the protocol for easy use, but also allows calling the functions of the KCP protocol directly (just like C code)
|
||||
- [kcp-rs](https://github.com/en/kcp-rs): The rust migration of KCP
|
||||
- [kcp-rust-native](https://github.com/b23r0/kcp-rust-native):KCP bindings for Rust
|
||||
- [lua-kcp](https://github.com/linxiaolong/lua-kcp): Lua extension of KCP, applicable for Lua server
|
||||
|
||||
@@ -165,6 +165,7 @@ vcpkg中的kcp库由Microsoft团队成员和社区贡献者保持最新状态。
|
||||
- [kcp-java](https://github.com/hkspirt/kcp-java): Java版本 KCP协议实现。
|
||||
- [kcp-netty](https://github.com/szhnet/kcp-netty): kcp的Java语言实现,基于netty。
|
||||
- [java-kcp](https://github.com/l42111996/java-Kcp): JAVA版本KCP,基于netty实现(包含fec功能)
|
||||
- [kcp.kt](https://github.com/jokelbaf/kcp.kt): 纯 Kotlin 多平台(Kotlin Multiplatform)实现的 KCP 协议,支持 JVM、Linux、Windows、macOS 和 iOS 等目标平台。
|
||||
- [csharp-kcp](https://github.com/l42111996/csharp-kcp): csharp版本KCP,基于dotNetty实现(包含fec功能)
|
||||
- [kcp-cpp](https://github.com/Unit-X/kcp-cpp): KCP 的多平台(Windows、MacOS、Linux)C++ 实现作为应用程序中的简单库。包含适用于所有平台的套接字处理和辅助函数。
|
||||
- [kcp-perl](https://github.com/Homqyy/kcp-perl): kcp的Perl实现,其是面向对象的,Perl-Like的。
|
||||
@@ -174,6 +175,7 @@ vcpkg中的kcp库由Microsoft团队成员和社区贡献者保持最新状态。
|
||||
- [KcpTransport](https://github.com/Cysharp/KcpTransport): kcp的csharp移植,实现了 Syn Cookie 握手、连接管理、不可靠通信、KeepAlive,未来还将支持加密。
|
||||
- [Kcp-CSharp](https://github.com/Molth/Kcp-CSharp): kcp的csharp移植,非托管包装器。
|
||||
- [kcp2k](https://github.com/vis2k/kcp2k/): Line-by-line translation to C#, with optional Server/Client on top.
|
||||
- [KcpSharpN](https://github.com/new1271/KcpSharpN): 将原始 C 语言源代码复刻到 Csharp 的移植,包含一个简易的协定包装器与原始的 KCP 协定呼叫
|
||||
- [kcp-rs](https://github.com/en/kcp-rs): KCP的 rust移植
|
||||
- [kcp-rust](https://github.com/Matrix-Zhang/kcp):新版本 KCP的 rust 移植
|
||||
- [tokio-kcp](https://github.com/Matrix-Zhang/tokio_kcp):rust tokio 的 kcp 集成
|
||||
@@ -225,7 +227,7 @@ KCP 成功的运行在多个用户规模上亿的项目上,为他们提供了
|
||||
- The enet is a good choice if your game allow 2 second lag.
|
||||
- **UDT is a bad idea**. It always sink into badly situation of more than serval seconds lag. And the recovery is not expected.
|
||||
- enet has the problem of lack of doc. And it has lots of functions that you may intrest.
|
||||
- kcp's doc is chinese. Good thing is the function detail which is writen in code is english. And you can use asio_kcp which is a good wrap.
|
||||
- kcp's doc is chinese. Good thing is the function detail which is written in code is english. And you can use asio_kcp which is a good wrap.
|
||||
- The kcp is a simple thing. You will write more code if you want more feature.
|
||||
- UDT has a perfect doc. UDT may has more bug than others as I feeling.
|
||||
|
||||
|
||||
35
ikcp.c
35
ikcp.c
@@ -272,6 +272,7 @@ ikcpcb* ikcp_create(IUINT32 conv, void *user)
|
||||
kcp->acklist = NULL;
|
||||
kcp->ackblock = 0;
|
||||
kcp->ackcount = 0;
|
||||
kcp->ackedlen = 0;
|
||||
kcp->rx_srtt = 0;
|
||||
kcp->rx_rttval = 0;
|
||||
kcp->rx_rto = IKCP_RTO_DEF;
|
||||
@@ -595,6 +596,7 @@ static void ikcp_parse_ack(ikcpcb *kcp, IUINT32 sn)
|
||||
IKCPSEG *seg = iqueue_entry(p, IKCPSEG, node);
|
||||
next = p->next;
|
||||
if (sn == seg->sn) {
|
||||
kcp->ackedlen += seg->len;
|
||||
if (kcp->ccops && kcp->ccops->on_pkt_acked) {
|
||||
pkt_rtt = -1;
|
||||
if (_itimediff(kcp->current, seg->ts) >= 0) {
|
||||
@@ -621,6 +623,7 @@ static void ikcp_parse_una(ikcpcb *kcp, IUINT32 una)
|
||||
IKCPSEG *seg = iqueue_entry(p, IKCPSEG, node);
|
||||
next = p->next;
|
||||
if (_itimediff(una, seg->sn) > 0) {
|
||||
kcp->ackedlen += seg->len;
|
||||
if (kcp->ccops && kcp->ccops->on_pkt_acked) {
|
||||
kcp->ccops->on_pkt_acked(kcp, seg->sn, seg->ts,
|
||||
seg->len, -1, seg->xmit);
|
||||
@@ -782,6 +785,8 @@ int ikcp_input(ikcpcb *kcp, const char *data, long size)
|
||||
IUINT32 maxack = 0, latest_ts = 0;
|
||||
int flag = 0;
|
||||
|
||||
kcp->ackedlen = 0;
|
||||
|
||||
if (ikcp_canlog(kcp, IKCP_LOG_INPUT)) {
|
||||
ikcp_log(kcp, IKCP_LOG_INPUT, "[RI] %d bytes", (int)size);
|
||||
}
|
||||
@@ -906,7 +911,8 @@ int ikcp_input(ikcpcb *kcp, const char *data, long size)
|
||||
acked_segs = kcp->snd_una - prev_una;
|
||||
prior_in_flight = prev_nsnd_buf;
|
||||
if (kcp->ccops && kcp->ccops->on_ack) {
|
||||
kcp->ccops->on_ack(kcp, acked_segs, prior_in_flight);
|
||||
kcp->ccops->on_ack(kcp, acked_segs, kcp->ackedlen,
|
||||
prior_in_flight);
|
||||
}
|
||||
else {
|
||||
if (kcp->cwnd < kcp->rmt_wnd) {
|
||||
@@ -975,6 +981,7 @@ void ikcp_flush(ikcpcb *kcp)
|
||||
IUINT32 rtomin;
|
||||
IUINT32 prior_cwnd;
|
||||
IUINT32 eff_cwnd, cur_inflight;
|
||||
IINT32 pacing_budget = -1;
|
||||
struct IQUEUEHEAD *p;
|
||||
int change = 0;
|
||||
int lost = 0;
|
||||
@@ -987,6 +994,10 @@ void ikcp_flush(ikcpcb *kcp)
|
||||
kcp->ccops->on_tick(kcp);
|
||||
}
|
||||
|
||||
if (kcp->ccops && kcp->ccops->pacing_rate) {
|
||||
pacing_budget = (IINT32)kcp->ccops->pacing_rate(kcp);
|
||||
}
|
||||
|
||||
prior_cwnd = kcp->cwnd;
|
||||
|
||||
seg.conv = kcp->conv;
|
||||
@@ -1084,10 +1095,6 @@ void ikcp_flush(ikcpcb *kcp)
|
||||
newseg->rto = kcp->rx_rto;
|
||||
newseg->fastack = 0;
|
||||
newseg->xmit = 0;
|
||||
|
||||
if (kcp->ccops && kcp->ccops->on_pkt_sent) {
|
||||
kcp->ccops->on_pkt_sent(kcp, newseg->sn, current, newseg->len, kcp->nsnd_buf - 1);
|
||||
}
|
||||
}
|
||||
|
||||
// check on_app_limited
|
||||
@@ -1147,6 +1154,15 @@ void ikcp_flush(ikcpcb *kcp)
|
||||
segment->wnd = seg.wnd;
|
||||
segment->una = kcp->rcv_nxt;
|
||||
|
||||
if (pacing_budget >= 0 && pacing_budget < (IINT32)segment->len) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (kcp->ccops && kcp->ccops->on_pkt_sent) {
|
||||
kcp->ccops->on_pkt_sent(kcp, segment->sn, current,
|
||||
segment->len, kcp->nsnd_buf, segment->xmit);
|
||||
}
|
||||
|
||||
size = (int)(ptr - buffer);
|
||||
need = IKCP_OVERHEAD + segment->len;
|
||||
|
||||
@@ -1162,6 +1178,10 @@ void ikcp_flush(ikcpcb *kcp)
|
||||
ptr += segment->len;
|
||||
}
|
||||
|
||||
if (pacing_budget >= 0) {
|
||||
pacing_budget -= (IINT32)segment->len;
|
||||
}
|
||||
|
||||
if (segment->xmit >= kcp->dead_link) {
|
||||
kcp->state = (IUINT32)-1;
|
||||
}
|
||||
@@ -1177,7 +1197,8 @@ void ikcp_flush(ikcpcb *kcp)
|
||||
// update ssthresh
|
||||
if (change) {
|
||||
if (kcp->ccops && kcp->ccops->on_fast_retransmit) {
|
||||
kcp->ccops->on_fast_retransmit(kcp, (IUINT32)change, kcp->nsnd_buf, prior_cwnd);
|
||||
kcp->ccops->on_fast_retransmit(kcp, (IUINT32)change,
|
||||
kcp->nsnd_buf, prior_cwnd);
|
||||
}
|
||||
else {
|
||||
IUINT32 inflight = kcp->snd_nxt - kcp->snd_una;
|
||||
@@ -1194,7 +1215,7 @@ void ikcp_flush(ikcpcb *kcp)
|
||||
kcp->ccops->on_timeout(kcp, prior_cwnd);
|
||||
}
|
||||
else {
|
||||
kcp->ssthresh = cwnd / 2;
|
||||
kcp->ssthresh = prior_cwnd / 2;
|
||||
if (kcp->ssthresh < IKCP_THRESH_MIN)
|
||||
kcp->ssthresh = IKCP_THRESH_MIN;
|
||||
kcp->cwnd = 1;
|
||||
|
||||
6
ikcp.h
6
ikcp.h
@@ -298,7 +298,8 @@ struct IKCPOPS
|
||||
const char *name;
|
||||
int (*init)(ikcpcb *kcp);
|
||||
void (*release)(ikcpcb *kcp);
|
||||
void (*on_ack)(ikcpcb *kcp, IUINT32 acked_segs, IUINT32 prior_in_flight);
|
||||
void (*on_ack)(ikcpcb *kcp, IUINT32 acked_segs, IUINT32 acked_bytes,
|
||||
IUINT32 prior_in_flight);
|
||||
void (*on_fast_retransmit)(ikcpcb *kcp, IUINT32 fast_retrans,
|
||||
IUINT32 inflight, IUINT32 prior_cwnd);
|
||||
void (*on_timeout)(ikcpcb *kcp, IUINT32 prior_cwnd);
|
||||
@@ -306,7 +307,7 @@ struct IKCPOPS
|
||||
void (*on_app_limited)(ikcpcb *kcp, IUINT32 inflight);
|
||||
void (*on_rtt)(ikcpcb *kcp, IINT32 rtt);
|
||||
void (*on_pkt_sent)(ikcpcb *kcp, IUINT32 sn, IUINT32 ts,
|
||||
IUINT32 len, IUINT32 inflight);
|
||||
IUINT32 len, IUINT32 inflight, IUINT32 xmit);
|
||||
void (*on_pkt_acked)(ikcpcb *kcp, IUINT32 sn, IUINT32 ts,
|
||||
IUINT32 len, IINT32 rtt, IUINT32 xmit);
|
||||
IUINT32 (*get_info)(ikcpcb *kcp, void *buf, IUINT32 bufsize);
|
||||
@@ -337,6 +338,7 @@ struct IKCPCB
|
||||
IUINT32 *acklist;
|
||||
IUINT32 ackcount;
|
||||
IUINT32 ackblock;
|
||||
IUINT32 ackedlen;
|
||||
void *user;
|
||||
char *buffer;
|
||||
int fastresend;
|
||||
|
||||
Reference in New Issue
Block a user