1. 从发送端解决(推荐)
适用条件: ①发送端是可以控制的.②微秒数量级的延迟可以接受
解决方法:发送时使用usleep(1)延迟1微秒发送,即发送频率不要过快,延迟1微妙发送,可以很好的解决这个问题.。
2.从接收端解决方法一
适用条件:①无法控制发送端发送数据的频率
解决方法: 用recvfrom函数收到数据之后尽快返回,进行下一次recvfrom,可以通过多线程+队列来解决.收到数据之后将数据放入队列中,另起一个线程去处理收到的数据;可以总结为服务器程序启动之出,接收端开辟两个线程,一个线程专门用于接收数据包,并存放在应用层的缓存区;另外一个线程用于专门处理和响应数据包请求,避免因为处理数据造成数据丢包。其本质上还是增大了缓冲区大小,只是将系统缓冲区转移到了自己的缓冲区。
3.从接收端解决方法二
适用条件:①使用方法2依然出现大规模丢包的情况,需要进一步优化
解决方法:使用setsockopt修改接收端的缓冲区大小。
4.最复杂的方式
在应用层实现丢包重发机制和超时机制,确保数据包不丢失。
NACK机制
说到丢包重传就不得不提到NACK技术,那么NACK是什么呢。它的全称是Negative Acknowledgment Packet,意思是否定确认包,说到这里我们应该可以联想到ACK(Acknowledgment Packet,确认包)。没错,二者的意思是相反的。ACK表示通知对方我收到了你发给我的数据包,NACK表示通知对方我没有收到你发给我的数据包。
那么问题来了,为什么会导致对方明明发送了响应的数据包,而我没有收到呢?其中的原因有很多,比如网络问题,因为中间路由器转发丢失,延时较大导致被NACK(可能数据包还在传输中,只是到达时间比较久)等。
基于上述原因,NACK的存在是非常有必要的。它能够及时的通知发送端重传相应的数据包,保证接收端音频和视频的正常播放。NACK其实是RTCP包的一种,用来是对 RTP 数据传输层进行反馈,它包类型是 205。
前向纠错机制FEC
在每个数据包中,您将添加一些关于前一个信息的信息,以防丢失,您需要重新构建它们(flexfec是WebRTC [1]中的新格式)。
顾名思义,FEC前向纠错,根据收到的包进行计算获取丢掉的包,而和大神沟通的结果就是 纠错神髓:收到的媒体包+冗余包 >= 原始媒体包数据
直到满足 收到的媒体包+ 冗余包 >= 原始媒体包数据 则进入恢复模式,恢复出2 4,然后一次输出2 3 4 5
所谓的Qos,也可以理解为抖动缓冲,解决udp包乱序、包重复的问题
NAT保活,保持udp连接,简言之:
当你向一个公网服务器发送数据时,服务器可以翻转IP和端口向你发数据, 但如果你长时间不发数据给服务器,服务器若想用之前的IP和端口向你发就不一定成功了。因为在路由器上的NAT映射可能已经失效,如果你是一直向服务器发送数据,那就不存在这个问题。
FEC的设计理念大多一样,编码/解码/回调函数:
1.encode,不区分输入内容,编码后输出输出冗余包数据;
2.decode,根据输入数据进行纠错,如果数据不是有序,则等待 (收到的媒体包+冗余包 >= 原始媒体包数据) 输出原数据
3.callback,一包一包数据输出,阻塞接口