udp丢包原因分析

7 篇文章 0 订阅
3 篇文章 0 订阅

什么会导致udp丢包呢,这里列举了如下几点原因:

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

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

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

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

  5. 发送的广播包或组播包在windws和linux下都接收正常,而arm上接收出现丢包。这个还不好解决,我的解决方法是大包切割成大小为1448的小包发送,每个包之间sleep 1毫秒,虽然笨,但有效。我这里mtu size为1500字节,减去udp包头8个字节,减去传输层几十个字节,实际数据位1448字节。(*_mem单位为页,4KB,其他选项为字节,见ip-sysctl.txt )
    除此之外还可以试试设置arm操作系统缓冲:

# 设置mtu size 1500最大
ifconfig eth0 mtu 1500
# 查看接收缓冲最大和默认大小。
sysctl -A | grep rmem
# 设置接收缓冲的最大大小
sysctl -w net.core.rmem_max=1048576
sysctl -w net.core.rmem_default=1048576
sysctl -w net.ipv4.udp_mem=1048576
sysctl -w net.ipv4.udp_rmem_min=1048576
  1. 局域网内不丢包,公网上丢包。这个问题我也是通过切割小包并sleep发送解决的。如果流量太大,这个办法也不灵了。

总之udp丢包总是会有的,如果上述方法解决不了,还有这个几个方法:

  • 要么减小流量
  • 要么换tcp协议传输
  • 么做丢包重传的工作

参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值