kcp icon indicating copy to clipboard operation
kcp copied to clipboard

请教如何丢包的问题?

Open sunzj opened this issue 2 years ago • 7 comments

https://github.com/skywind3000/kcp/issues/230#issuecomment-541292962 "KCP 任何情况下都不会丢包,自动重传协议本身就是干这个的。"

怎样在ikcp_waitsnd 中累积到一定数据的时候,或重传次数到达一定的阈值时,直接丢包?还是kcp内部不会丢包,只能在上层发现ikcp_waitsnd中累积过多,直接将要送入kcp的数据包丢掉?

sunzj avatar Dec 14 '21 08:12 sunzj

没看懂,你要主动丢包么?

skywind3000 avatar Dec 14 '21 08:12 skywind3000

没看懂,你要主动丢包么?

是的,项目在做PCM的音频传送,实时要求很高,多次重传还没成功,则该份数据再发过去已经没多大意义,希望可以在重传次数达到一定阈值时,直接将未传送的数据丢弃。

sunzj avatar Dec 14 '21 08:12 sunzj

OK,合理,等我周末支持下。

skywind3000 avatar Dec 14 '21 08:12 skywind3000

OK,合理,等我周末支持下。

周末有空看没, 尝试把snd_buf中数据往前移,同时更新 kcp->nsnd_buf--; kcp->snd_nxt--;及snd_buf中剩余数据的sn,还是有问题。。。

static void ikcp_flush_sndbuf(ikcpcb *kcp, int maxrto) { struct IQUEUEHEAD *p, *next; int snd_drop_num = 0;

 for (p = kcp->snd_buf.next; p != &kcp->snd_buf; p = next) {
     IKCPSEG *seg = iqueue_entry(p, IKCPSEG, node);
     next = p->next;
     if ((seg->rto > maxrto)) {
         iqueue_del(p);
         ikcp_segment_delete(kcp, seg);
         kcp->nsnd_buf--;
         kcp->snd_nxt--;
         snd_drop_num++;
         continue;
     }    
     if (snd_drop_num > 0) { 
          seg->sn -= snd_drop_num;
     }    
 }    
 ikcp_shrink_buf(kcp);
 printf("flush sndbuf %d buf\n", snd_drop_num);

}

sunzj avatar Dec 20 '21 08:12 sunzj

OK,合理,等我周末支持下。

请问一下,实现的难度大么,是只需要对 snd_queue,进行清空就可以了么

symsimmy avatar Mar 19 '22 04:03 symsimmy

OK,合理,等我周末支持下。

周末有空看没, 尝试把snd_buf中数据往前移,同时更新 kcp->nsnd_buf--; kcp->snd_nxt--;及snd_buf中剩余数据的sn,还是有问题。。。

static void ikcp_flush_sndbuf(ikcpcb *kcp, int maxrto) { struct IQUEUEHEAD *p, *next; int snd_drop_num = 0;

 for (p = kcp->snd_buf.next; p != &kcp->snd_buf; p = next) {
     IKCPSEG *seg = iqueue_entry(p, IKCPSEG, node);
     next = p->next;
     if ((seg->rto > maxrto)) {
         iqueue_del(p);
         ikcp_segment_delete(kcp, seg);
         kcp->nsnd_buf--;
         kcp->snd_nxt--;
         snd_drop_num++;
         continue;
     }    
     if (snd_drop_num > 0) { 
          seg->sn -= snd_drop_num;
     }    
 }    
 ikcp_shrink_buf(kcp);
 printf("flush sndbuf %d buf\n", snd_drop_num);

}

请问下,后面有解决安全丢包的问题么,成熟的方案是什么呀?

symsimmy avatar Mar 19 '22 13:03 symsimmy

OK,合理,等我周末支持下。

周末有空看没, 尝试把snd_buf中数据往前移,同时更新 kcp->nsnd_buf--; kcp->snd_nxt--;及snd_buf中剩余数据的sn,还是有问题。。。 static void ikcp_flush_sndbuf(ikcpcb *kcp, int maxrto) { struct IQUEUEHEAD *p, *next; int snd_drop_num = 0;

 for (p = kcp->snd_buf.next; p != &kcp->snd_buf; p = next) {
     IKCPSEG *seg = iqueue_entry(p, IKCPSEG, node);
     next = p->next;
     if ((seg->rto > maxrto)) {
         iqueue_del(p);
         ikcp_segment_delete(kcp, seg);
         kcp->nsnd_buf--;
         kcp->snd_nxt--;
         snd_drop_num++;
         continue;
     }    
     if (snd_drop_num > 0) { 
          seg->sn -= snd_drop_num;
     }    
 }    
 ikcp_shrink_buf(kcp);
 printf("flush sndbuf %d buf\n", snd_drop_num);

}

请问下,后面有解决安全丢包的问题么,成熟的方案是什么呀?

丢包方案和KCP的设计理念天生就不相符,后面我改了一个版本,提供一下思路:欺骗KCP,当一个包发送多次后仍没有被接收到,则把里面的内容替换掉(相当于丢包)。

这会破坏KCP原有的机制:比如导致乱序等,需要在KCP之上再加上一层简单协议来进行排序,什么时候开启丢包等。

sunzj avatar Dec 29 '23 06:12 sunzj