文章目录
UDP服务端丢包-发送频率过高导致丢包
UDP主要丢包原因
整体可以从三个维度考虑,
发送方丢UDP包、网络过程中丢UDP包、接收方丢UDP包
发送方丢UDP包
发送方丢包:内部缓冲区(internal buffers)已满,并且发送速度过快(即发送两个报文之间的间隔过短);
待验证,目前没有发现丢包情况,不知道怎么验证, 暂不关注。
发送缓冲区,需要配置 socket选项 SO_SNDBUF
进程调用send发送的数据的时候,最简单情况(也是一般情况),将数据拷贝进入socket的内核发送缓冲区之中,然后send便会在上层返回。
换句话说,send返回之时,数据不一定会发送到对端去(和write写文件有点类似),send仅仅是把应用层buffer的数据拷贝进socket的内核发送buffer中。
网络过程中丢UDP包
当报文过大时,稳定性会大大减弱。这是因为当报文过大时会被分割,使得每个分割块(翻译可能有误差,原文是fragmentation)的长度小于MTU,然后分别发送,并在接收方重新组合(reassemble),但是如果其中一个报文丢失,那么其他已收到的报文都无法返回给程序,也就无法得到完整的数据了。
接收方丢UDP包,发送频率过高导致丢包,主要会造成接收方自身丢包。
接收端处理时间过长导致丢包:调用recv方法接收端收到数据后,处理数据花了一些时间,处理完后再次调用recv方法,在这二次调用间隔里,发过来的包可能丢失。对于这种情况可以修改接收端,将包接收后存入一个缓冲区,然后迅速返回继续recv。
解决思路:要在收到一个数据包后最短的时间内重新回到监听状态,其间要尽量避免复杂的操作(比较好的解决办法是使用多线程回调机制)。
总结: UDP发包速率过快,突发大数据流量超过了缓冲区上限(默认缓存太小,不能及时接收数据。 连续多个UDP包超过了UDP接收缓冲区大小)。
发送频率过高导致丢包如何解决?
为什么发送频率过高导致丢包?
很多人会不理解发送速度过快为什么会产生丢包,原因就是UDP的SendTo不会造成线程阻塞,也就是说,UDP的SentTo不会像TCP中的SendTo那样,直到数据完全发送才会return回调用函数,它不保证当执行下一条语句时数据是否被发送。(SendTo方法是异步的)这样,如果要发送的数据过多或者过大,那么在缓冲区满的那个瞬间要发送的报文就很有可能被丢失。至于对“过快”的解释,作者这样说:“A few packets a second are not an issue; hundre