zoukankan      html  css  js  c++  java
  • 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协议传输,要么做丢包重传的工作。

     
     
  • 相关阅读:
    Java找N个数中最小的K个数,PriorityQueue和Arrays.sort()两种实现方法
    POJ 1661 Help Jimmy(C)动态规划
    LeetCode第8场双周赛(Java)
    Eclipse访问外部网站(比如:CSDN首页)
    LeetCode第151场周赛(Java)
    LeetCode第152场周赛(Java)
    Eclipse Block Selection(块选择)快捷键 Alt + Shift + A
    PAT(B) 1090 危险品装箱(Java)
    PAT(B) 1050 螺旋矩阵(Java:24分)
    PAT(B) 1045 快速排序(C)
  • 原文地址:https://www.cnblogs.com/yorkyang/p/7384310.html
Copyright © 2011-2022 走看看