mirror of
https://github.com/skywind3000/kcp.git
synced 2026-08-19 22:23:28 +08:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
32da082e52 |
69
.gitignore
vendored
69
.gitignore
vendored
@@ -1,14 +1,69 @@
|
||||
*.o
|
||||
*
|
||||
!*/
|
||||
!*.*
|
||||
|
||||
*.obj
|
||||
*.o
|
||||
*.lib
|
||||
*.ipch
|
||||
*.pch
|
||||
*.sdf
|
||||
*.exe
|
||||
*.a
|
||||
*.p
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
*.ncb
|
||||
*.sdf
|
||||
|
||||
.tasks
|
||||
.root
|
||||
__pycache__
|
||||
/build/*
|
||||
/example/build/*
|
||||
/gateway/build/*
|
||||
|
||||
/.vscode/*
|
||||
/.idea/*
|
||||
/.DS_Store
|
||||
/.env
|
||||
/build/*
|
||||
/.vs/*
|
||||
/.cache/*
|
||||
/testing/*.xlsx
|
||||
/testing/*.txt
|
||||
/update.cmd
|
||||
.vs
|
||||
/visualstudio/Debug/*
|
||||
/visualstudio/Release/*
|
||||
/visualstudio/x64/*
|
||||
/visualstudio/bbnet/*
|
||||
/visualstudio/.vs/*
|
||||
/visualstudio/bbnet.vcxproj.user
|
||||
|
||||
/x64/*
|
||||
/Debug/*
|
||||
/Release/*
|
||||
/bbnet/*
|
||||
|
||||
*.vcxproj.user
|
||||
/update.cmd
|
||||
|
||||
*.pcap
|
||||
*.win32
|
||||
*.linux
|
||||
*.linux2
|
||||
*.log
|
||||
|
||||
*.pyc
|
||||
*.pyo
|
||||
*.pyd
|
||||
|
||||
__pycache__/*
|
||||
|
||||
/session*.md
|
||||
/skills/*
|
||||
|
||||
/.qoder/*
|
||||
/.opencode/*
|
||||
/.claude/*
|
||||
/.iflow/*
|
||||
|
||||
nul
|
||||
|
||||
|
||||
|
||||
@@ -22,6 +22,8 @@ KCP是一个快速可靠协议,能以比 TCP 浪费 10%-20% 的带宽的代价
|
||||
|
||||
整个协议只有 ikcp.h, ikcp.c两个源文件,可以方便的集成到用户自己的协议栈中。也许你实现了一个P2P,或者某个基于 UDP的协议,而缺乏一套完善的ARQ可靠协议实现,那么简单的拷贝这两个文件到现有项目中,稍微编写两行代码,即可使用。
|
||||
|
||||
**注意:KCP 目前更新到 V2,增加了可插拔的流控算法机制,可以不改协议的情况下替换流控算法,老的 v1 足够稳定,我放到了 v1 这个 branch 里。**
|
||||
|
||||
|
||||
# 技术特性
|
||||
|
||||
|
||||
35
ikcp.c
35
ikcp.c
@@ -272,7 +272,6 @@ 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;
|
||||
@@ -596,7 +595,6 @@ 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) {
|
||||
@@ -623,7 +621,6 @@ 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);
|
||||
@@ -785,8 +782,6 @@ 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);
|
||||
}
|
||||
@@ -911,8 +906,7 @@ 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, kcp->ackedlen,
|
||||
prior_in_flight);
|
||||
kcp->ccops->on_ack(kcp, acked_segs, prior_in_flight);
|
||||
}
|
||||
else {
|
||||
if (kcp->cwnd < kcp->rmt_wnd) {
|
||||
@@ -981,7 +975,6 @@ 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;
|
||||
@@ -994,10 +987,6 @@ 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;
|
||||
@@ -1095,6 +1084,10 @@ 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
|
||||
@@ -1154,15 +1147,6 @@ 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;
|
||||
|
||||
@@ -1178,10 +1162,6 @@ 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;
|
||||
}
|
||||
@@ -1197,8 +1177,7 @@ 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;
|
||||
@@ -1215,7 +1194,7 @@ void ikcp_flush(ikcpcb *kcp)
|
||||
kcp->ccops->on_timeout(kcp, prior_cwnd);
|
||||
}
|
||||
else {
|
||||
kcp->ssthresh = prior_cwnd / 2;
|
||||
kcp->ssthresh = cwnd / 2;
|
||||
if (kcp->ssthresh < IKCP_THRESH_MIN)
|
||||
kcp->ssthresh = IKCP_THRESH_MIN;
|
||||
kcp->cwnd = 1;
|
||||
|
||||
6
ikcp.h
6
ikcp.h
@@ -298,8 +298,7 @@ struct IKCPOPS
|
||||
const char *name;
|
||||
int (*init)(ikcpcb *kcp);
|
||||
void (*release)(ikcpcb *kcp);
|
||||
void (*on_ack)(ikcpcb *kcp, IUINT32 acked_segs, IUINT32 acked_bytes,
|
||||
IUINT32 prior_in_flight);
|
||||
void (*on_ack)(ikcpcb *kcp, IUINT32 acked_segs, 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);
|
||||
@@ -307,7 +306,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 xmit);
|
||||
IUINT32 len, IUINT32 inflight);
|
||||
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);
|
||||
@@ -338,7 +337,6 @@ struct IKCPCB
|
||||
IUINT32 *acklist;
|
||||
IUINT32 ackcount;
|
||||
IUINT32 ackblock;
|
||||
IUINT32 ackedlen;
|
||||
void *user;
|
||||
char *buffer;
|
||||
int fastresend;
|
||||
|
||||
Reference in New Issue
Block a user