游戏网络 UDP+FEC+KCP

        FEC主要针对原始传输数据生成冗余的数据,然后一起进行传输,在传输过程中,如果部分原始数据丢失了,可以通过收到的部分冗余信息和部分原始数据进行原始数据的还原。这个技术在流媒体中运用比较多,在网络延迟的时候保证视频观看体验丝滑。简单说就是用流量换数据完整。

        在即时性要求比较高的游戏中,为了提升玩家的体验和即时性,网络传输会采用可靠UDP(如KCP)而不是TCP,主要是TCP传输时间开销比较大。但仅是可靠UDP,面对网络延迟还是捉襟见肘,此时在协议栈上加入FEC技术是一个不错的选择。

        那么如何接入FEC呢?

        这里推荐学习charp-kcp,实现了kcp+fec,其中FEC是RS-FEC算法。

FEC主要是通过K份原始数据,生成M份冗余数据,K+M数据组成一份FEC包,FEC包中的任意K份数据,可以还原出所有原始数据。

csharp-kcp中的FEC协议:

        原始数据: | sequenceID | flag | bodyLen |  source data |

        冗余数据: | sequenceID | flag | redundant data |

sequenceID: 每份数据的序号

flag:区分原始数据和冗余数据

bodylen:原始数据的长度

redundant data:冗余数据,长度取决于K份数据中最长的bodyLen

发送端:

先依次接收上层(KCP)K份数据进行缓存并直接转发下层协议(UDP),当缓存数等于K时,使用FEC算法生成M份原始数据,向下层协议分开发送M份原始数据,然后释放K份缓存。

接收端:

通过flag可以判断数据是原始数据还是冗余数据,原始数据缓存并转发上层协议(KCP),冗余数据同样进行缓存。

通过数据的sequenceID可以简单的得知,原始数据和冗余数据是否来自同一个FEC包中。

在收到每一份数据后,都检查这份数据所在的FEC包中的原始数据是否都已经接收了,如果没有,是否已经收到FEC包中K份数据,如果是,直接进行解码,将解出的原始数据转发给上层协议。然后这份FEC包相关的缓存数据就可以移除了。

注意:

kcp最佳实践中提及:为了进一步提高传输速度,下层协议也许会使用前向纠错技术。需要注意,前向纠错会根据冗余信息解出原始数据包。相同的原始数据包不要两次input到KCP,否则将会导致 kcp以为对方重发了,这样会产生更多的ack占用额外带宽。

也就是说:有可能FEC刚解出原始数据,之后又接收到已被解码的原始数据。如果继续往上层转发,对kcp来说是收到两次同样的数据,从而误以为是重发,导致产生更多的ack占用额外带宽。最好对接收过的原始数据进行记录,及时剔除重复的数据。

开发时可以关注的:

1 减少解码导致的原始数据重复input

2 缓存数据的内存多次开辟和释放(对客户端来说就是很多GC)

3 多层协议数据封装同样有内存块多次开辟和释放的问题(在csharp-kcp中的做法是:申请空间时先为下层协议留好足够的协议头空间)

4 FEC协议头部分,主要还是根据自己的协议栈进行设计。csharp-kcp中上层协议是KCP,KCP的部分本身会对发送的数据做一些拆分,到FEC层的时候数据量比较小,因此可以把一次发送作为FEC包的一份数据。如果换成其他协议栈,且每次发送数据量比较大,最好在FEC上层做一些分片的操作。

李超:WebRTC传输与服务质量 - 知乎 (zhihu.com)

谈谈网络通信中的 FEC 基础_Jhuster的专栏的技术博客_51CTO博客

流媒体弱网优化之路(FEC)——FEC原理简介_qw225967的博客-CSDN博客_fec原理

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值