• udp丢包 处理


    转自:

    自己在做UDP传输时遇到的问题,接收端没设置缓存,结果总是丢包。

    看到这篇文章设置了一下接收缓存就好
    int nRecvBuf=32*1024;//设置为32K  
    setsockopt(s,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int)); 
    http://www.cnweblog.com/fly2700/archive/2011/09/19/317825.html


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

    1.调用recv方法接收端收到数据后,处理数据花了一些时间,处理完后再次调用recv方法,在这二次调用间隔里,发过来的包可能丢失。对于这种情况可以修改接收端,将包接收后存入一个缓冲区,然后迅速返回继续recv。
    2.发送的包巨大丢包。虽然send方法会帮你做大包切割成小包发送的事情,但包太大也不行。例如超过30K的一个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));
    4.发送的包频率太快,虽然每个包的大小都小于mtu size 但是频率太快,例如40多个mut size的包连续发送中间不sleep,也有可能导致丢包。这种情况也有时可以通过设置socket接收缓冲解决,但有时解决不了。
    5.发送的广播包或组播包在windws和Linux下都接收正常,而arm上接收出现丢包。这个还不好解决,我的解决方法是大包切割成大小为1448的小包发送,每个包之间sleep 1毫秒,虽然笨,但有效。我这里mtu size为1500字节,减去udp包头8个字节,减去传输层几十个字节,实际数据位1448字节。
    除此之外还可以试试设置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
    6,局域网内不丢包,公网上丢包。这个问题我也是通过切割小包并sleep发送解决的。如果流量太大,这个办法也不灵了。


    总之udp丢包总是会有的,如果出现了用我的方法解决不了,还有这个几个方法: 要么减小流量,要么换tcp协议传输,要么做丢包重传的工作。

     
     
  • 相关阅读:
    自己写的jQuery放大镜插件效果(一)(采用一张大图和一张小图片的思路)
    javascript 节点操作拷贝节点cloneNode()
    javascript节点操作移出节点removeChild()
    写的一个封拆包代码
    C#_socket拆包_封包_模拟乱序包
    VS2010使用DX报错 VS报错之混合模式程序集是针对“v1.1.4322”版的运行时生成的,在没有配置其他信息的情况下,无法在 4.0 运行时中加载该程序集。
    C#_C++_SDK_WM_KEYDOWN人物卡顿延迟解决方法
    MYSQL游标的使用
    MYSQL异常和错误机制
    CRM中的一个函数,保存一下,别系统被ぅ崩坏就麻烦了.
  • 原文地址:https://www.cnblogs.com/yorkyang/p/7384310.html
Copyright © 2020-2023  润新知