UDP丢包原因

一、主要丢包原因

1、接收端处理时间过长导致丢包:调用recv方法接收端收到数据后,处理数据花了一些时间,处理完后再次调用recv方法,在这二次调用间隔里,发过来的包可能丢失。对于这种情况可以修改接收端,将包接收后存入一个缓冲区,然后迅速返回继续recv。

2、发送的包巨大丢包:虽然send方法会帮你做大包切割成小包发送的事情,但包太大也不行。例如超过50K的一个udp包,不切割直接通过send方法发送也会导致这个包丢失。这种情况需要切割成小包再逐个send。

3、发送的包较大,超过接受者缓存导致丢包:包超过mtu size数倍,几个大的udp包可能会超过接收者的缓冲,导致丢包。这种情况可以设置socket接收缓冲。以前遇到过这种问题,我把接收缓冲设置成64K就解决了。
int nRecvBuf=32*1024;//设置为32K
setsockopt(s,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int));

具体设置代码可以参考下面链接:
http://blog.sina.com.cn/s/blog_a459dcf5010153mp.html

4、发送的包频率太快:虽然每个包的大小都小于mtu size 但是频率太快,例如40多个mut size的包连续发送中间不sleep,也有可能导致丢包。这种情况也有时可以通过设置socket接收缓冲解决,但有时解决不了。所以在发送频率过快的时候还是考虑sleep一下吧。

5、局域网内不丢包,公网上丢包。这个问题我也是通过切割小包并sleep发送解决的。如果流量太大,这个办法也不灵了。总之udp丢包总是会有的,如果出现了用我的方法解决不了,还有这个几个方法: 要么减小流量,要么换tcp协议传输,要么做丢包重传的工作。

二、具体问题分析

1.发送频率过高导致丢包

很多人会不理解发送速度过快为什么会产生丢包,原因就是UDP的SendTo不会造成线程阻塞,也就是说,UDP的SentTo不会像TCP中的SendTo那样,直到数据完全发送才会return回调用函数,它不保证当执行下一条语句时数据是否被发送。(SendTo方法是异步的)这样,如果要发送的数据过多或者过大,那么在缓冲区满的那个瞬间要发送的报文就很有可能被丢失。至于对“过快”的解释,作者这样说:“A few packets a second are not an issue; hundreds or thousands may be an issue.”(一秒钟几个数据包不算什么,但是一秒钟成百上千的数据包就不好办了)。 要解决接收方丢包的问题很简单,首先要保证程序执行后马上开始监听(如果数据包不确定什么时候发过来的话),其次,要在收到一个数据包后最短的时间内重新回到监听状态,其间要尽量避免复杂的操作(比较好的解决办法是使用多线程回调机制)。

2.报文过大丢包

至于报文过大的问题,可以通过控制报文大小来解决,使得每个报文的长度小于MTU。以太网的MTU通常是1500 bytes,其他一些诸如拨号连接的网络MTU值为1280 bytes,如果使用speaking这样很难得到MTU的网络,那么最好将报文长度控制在1280 bytes以下。

3.发送方丢包

发送方丢包:内部缓冲区(internal buffers)已满,并且发送速度过快(即发送两个报文之间的间隔过短); 接收方丢包:Socket未开始监听; 虽然UDP的报文长度最大可以达到64 kb,但是当报文过大时,稳定性会大大减弱。这是因为当报文过大时会被分割,使得每个分割块(翻译可能有误差,原文是fragmentation)的长度小于MTU,然后分别发送,并在接收方重新组合(reassemble),但是如果其中一个报文丢失,那么其他已收到的报文都无法返回给程序,也就无法得到完整的数据了。

时间: 2024-07-30 10:09:37

UDP丢包原因的相关文章

udp丢包 又是udp丢包

什么会导致udp丢包呢,我这里列举了如下几点原因: 1.调用recv方法接收端收到数据后,处理数据花了一些时间,处理完后再次调用recv方法,在这二次调用间隔里,发过来的包可能丢失.对于这种情况可以修改接收端,将包接收后存入一个缓冲区,然后迅速返回继续recv. 2.发送的包巨大丢包.虽然send方法会帮你做大包切割成小包发送的事情,但包太大也不行.例如超过30K的一个udp包,不切割直接通过send方法发送也会导致这个包丢失.这种情况需要切割成小包再逐个send. 3.发送的包较大,超过mtu

Socket编程 (异步通讯,解决Udp丢包) - Part4

原文http://www.cnblogs.com/zengqinglei/archive/2013/05/15/3079007.html Socket编程 (异步通讯,解决Udp丢包) 对于基于socket的udp协议通讯,丢包问题大家应该都见怪不怪了,但我们仍然希望在通讯方面使用Udp协议通讯,因为它即时,消耗资源 少,响应迅速,灵活性强无需向Tcp那样建立连接消耗很长的时间等等很有优势的理由让我们对Udp通讯寄予了厚望.但它也存在一个不好的特点,经常丢包是 时常发生的事.可能各位大侠已经有了

路由不定时丢包原因和解决方法

关于路由器丢包的原因有很多种,本篇介绍如何判断是否是路由器丢包和解决的方法. 一.内存碎片是指路由器内存被划分了许多不连续的块.他将导致内存利用率降低,严重时可能会产生内存错误,影响路由器的性能.它也会导致路由器报文丢失的问题,其实不仅路由器的内存存在碎片问题,普通的硬盘也存在这种问题. 如微软操作系统中就自带一个碎片整理工具,可以保障用户来整理硬盘中的碎片,以提高硬盘的存储容量以及存储性能.这里指的内存碎片其实跟硬盘碎片是类似的. 二.那该如何判断路由器的内存是否存在碎片呢?这里主要借助的是灵

UDP 丢包 急。。谢谢

问题描述 我的udpclient端发送的太快,udpserver来不及接收?据说可以使用缓冲区来处理..麻烦哪位大牛帮忙说说怎么做?非常感谢. 解决方案 解决方案二:UDP协议丢包很正常.解决方案三:UDP就是丢包的没办法,如果你要自己实现UDP的差错控制的话,那还不如直接使用TCP解决方案四:我知道丢包很严重,可是这个对实时性要求很强,选择UDP是不错的..主要是我在接收的时候来不及接..我做处理了,.处理就是写入io流.如果不处理的话就有足够的时间来接了..麻烦哪位能说下,如何能把两者分开,

java udp丢包严重

问题描述 我在客户端一次性发了100000万条消息,抓包工具也显示所有包都收到了,可是程序里就是有部分包收不到,这是为什么? 解决方案 解决方案二:10亿?求程序处理方案,或者代码解决方案三:被底层操作系统给丢掉了?解决方案四:可是抓包工具全部抓到了呀解决方案五:你做压力测试么?搞这么大数据量解决方案六:这么说一定是程序原因了?同求代码和处理方法

iperf UDP测试丢包问题分析

本文目的 分析同一region下两台vpc类型ECS之间iperf测试UDP丢包问题排查 问题描述 用户在同一个region下的两台ECS分属两个vpc,两个vpc通过高速通道打通,然后通过iperf测试二者内网之间UDP的丢包情况,当测试带宽达到50M以上的时候,出现了丢包现象,且随着带宽的增加,丢包率出现增长趋势. ECS A:iperf -c <ECS_B_IP> -u -b <bandwidth> ECS B: iperf -s -u 问题分析 vpc类型ECS A与vpc

rt-同时接收多个udp时丢包

问题描述 同时接收多个udp时丢包 udp广播,多个客户端同时回馈.广播端接收反馈数据会出现丢包.在android上测试,好的手机丢包情况明显改善.请教下有没有好的解决方案彻底解决. 解决方案 UDP丢包问题 解决方案二: UDP本身就是不可靠的.如果有丢包,你可以尝试再次广播,多发送几次,来接收数据

ping 丢包或不通时链路测试说明

当客户端访问目标服务器出现 ping 丢包或 ping 不通时,可以通过 tracert 或 mtr 等工具进行链路测试来判断问题来源.本文先介绍了进行链路测试的相关工具,然后对测试结果分析及测试步骤进行了说明. 链路测试工具介绍 根据操作系统类型的不同,链路测试所使用的工具也有所不同.分别简要介绍如下. Linux 环境下链路测试工具介绍 Windows 环境下链路测试工具介绍 Linux 环境下链路测试工具介绍 traceroute 命令行工具 mtr 命令行工具(建议优先使用) trace

网络通信丢包+IDC机房托管服务器之间通信不畅的问题

网络端口采用了1000M速率时候出现网络通信丢包+IDC机房托管服务器之间通信不畅. 网络故障: 交换机端口1000M,网卡也是1000M,网卡配置正常.ping时候间隔丢包. 表现为网络通信丢包,并且排除了其他网络设置故障. 故障原因:使用的网线非严格质量的超六类网线,网线质量无法达1000M. 解决方法:将交换机端口设置成100M端口:或者更换为超六类网线. 故障出现情况:网络端口采用了1000M速率时候出现网络通信丢包. 目录: 1.实例场景.网络端口采用了1000M速率时候出现网络通信丢