精华内容
参与话题
问答
  • UDP接收缓冲区溢出导致丢包

    千次阅读 2019-10-28 10:57:25
    最近实验室项目遇到了一个很有意思的小问题,在线下debug的时候...这个图就是整体架构,P从File读取的数据通过UDP发送给模型M进行预测处理等操作,模型M将预测结果发送给前端Player进行展示,结果发现P发送的数据一...

    最近实验室项目遇到了一个很有意思的小问题,在线下debug的时候,为了模拟线上环境,数据源直接从文件读取,但是线上实际数据收发频率很慢,差不多一秒几条数据,但是debug时为了节省时间每次读取文件数据发送出去的时候并没有延迟。这就导致了问题。

    这个图就是整体架构,P从File读取的数据通过UDP发送给模型M进行预测处理等操作,模型M将预测结果发送给前端Player进行展示,结果发现P发送的数据一切正常,player展示出来的结果莫名其妙缺少很多数据点,思考后发现问题,原来P端每次读取到一条数据直接send,中间没有暂停,而M端进行预测得过程比较耗时,所以导致在预测的时候,M的内核UDP缓冲区收满了,后来的数据包被丢弃,导致后面Player显示缺少数据。这里有两个解决方法:1,P端睡眠一定时间,这也是比较常用的方法。2,修改M端套接字的接受缓冲区大小。说到这里想补充一下TCP和UDP的缓冲区知识,每个SOCKET都在内核中被映射为一个文件,每个socket对应两个缓冲区也就是收发缓冲区,UDP其实也有发送缓冲区(但是不像TCP那样,并不会缓存多个数据包),TCP是永远不会出现像上面UDP遇到的问题的,因为TCP的流量控制机制,会根据接收窗口大小严格控制发送窗口的大小。而UDP不可靠,并没有流量控制的机制,所以会导致丢包。

    展开全文
  • udp丢包 又是udp丢包

    2017-10-09 11:04:00
    什么会导致udp丢包呢,我这里列举了如下几点原因: 1.调用recv方法接收端收到数据后,处理数据花了一些时间,处理完后再次调用recv方法,在这二次调用间隔里,发过来的包可能丢失。对于这种情况可以修改接收端,将包...

    什么会导致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协议传输,要么做丢包重传的工作

    展开全文
  • 网络环境:1000M,直连,多网卡 系统:Linux version 3.19.0 接收模式:udp模式的raw socket(优化的话,可以直接通过网卡处理) 发送模式:udp模式的raw socket(优化的话,可以直接通过网卡处理),单线程/多线程...

    编写一个转发模块,虽然没有要求一转多时要达到多少路(不采用组播的情况下,单纯的一路转成多路),但是本着物尽其用的原则,尽可能测试一下极限。

    网络环境:1000M,直连,多网卡

    系统:Linux version 3.19.0

    接收模式:udp模式的raw socket(优化的话,可以直接通过网卡处理)

    发送模式:udp模式的raw socket(优化的话,可以直接通过网卡处理),单线程/多线程

                         2M               1转N

    设备A   ---------------->   转发设备  ---------------->  设备B

     

    但N大到一定程度时,发现发送丢包。

    注意,是转发设备发送丢包,不是设备B接收丢包。

    设备B接收丢包是可以理解的,毕竟2M码率本身的突发性相当高,1转N时,这个突发率更加扩大。

    但是发送丢包是一个什么情况,sendto的返回值都进行了判断,如果异常是会出现打印信息的,但是没有异常出现。

    上网查资料。其中最靠谱的是

    http://www.cnblogs.com/mengyan/archive/2012/10/04/2711340.html

    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.”(一秒钟几个数据包不算什么,但是一秒钟成百上千的数据包就不好办了)。

     

    发送方丢包:内部缓冲区(internal buffers)已满,并且发送速度过快(即发送两个报文之间的间隔过短); 

    但是更让人郁闷的事情出现了。无论是网上资料,还是询问同事,与tcp不同,发送这一块没有缓存区啊。

    问题的,已经设置SO_SNDBUF为64M,修改系统值为128M,设置后获取到的SO_SNDBUF为128M。

    现在就是在此种情况下发送丢包,128M是什么概念啊,所以基本可以排除这一块的问题。

    通过命令watch netstat -s,可以明确的看出 Ip 项下的 outgoing packets dropped 持续增长,也就意味着确实是发送丢包。

    然后就通过outgoing packets dropped ,sendto频率过快等等关键词开始查资料,结果让人蓝瘦香菇啊

    阴差阳错的情况下,查到了 IOCTLS

    http://blog.csdn.net/wl_haanel/article/details/5305159

    SIOCGIFTXQLEN , SIOCSIFTXQLEN 使用 ifr_qlen 读取 或 设置 设备的 传输队列长度. 设置 传输队列长度 是 特权操作.

     

    于是通过

    struct ifreq ifr;

    memset(&ifr, 0, sizeof(ifr));
    strncpy(ifr.ifr_name, "eth0", sizeof(ifr.ifr_name));

    if (-1 == ioctl(sock_, SIOCGIFTXQLEN, &ifr))
        PLOG(ERROR) << "failed to get dev eth0 queue length";
    LOG(KEY) << "Dev eth0 queue length " << ifr.ifr_qlen;

    获取到eth0上的队列长度为1000,设置成10000试试

    struct ifreq ifr;
    memset(&ifr, 0, sizeof(ifr));
    strncpy(ifr.ifr_name, "eth0", sizeof(ifr.ifr_name));
    ifr.ifr_qlen = 10000;
    if (-1 == ioctl(sock_, SIOCSIFTXQLEN, &ifr))
      PLOG(ERROR) << "failed to set dev eth0 queue length";
    if (-1 == ioctl(sock_, SIOCGIFTXQLEN, &ifr))
      PLOG(ERROR) << "failed to get dev eth0 queue length";
    LOG(KEY) << "Dev eth0 queue length " << ifr.ifr_qlen;

    果然,发现好了,没有发送丢包了

    去掉SO_SNDBUF的设置,获取下SO_SNDBUF,才多少K,再测试,仍然没有发送丢包。

     

    结论:

    sendto过快导致发送丢包,是因为发送队列满了,如果说缓存区,估计大部分人都将误解。

     

    至于接收方因为突发率导致接收丢包的问题,那么就要在发送方进行发送平滑进行解决。

    转载于:https://www.cnblogs.com/liaokang/p/6003334.html

    展开全文
  • [转载]udp丢包 又是udp丢包

    千次阅读 2012-09-19 10:11:38
    什么会导致udp丢包呢,我这里列举了如下几点原因: 1.调用recv方法接收端收到数据后,处理数据花了一些时间,处理完后再次调用recv方法,在这二次调用间隔里,发过来的包可能丢失。对于这种情况可以修改接收端,将包...

    udp丢包 又是udp丢包

    原创
    什么会导致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协议传输,要么做丢包重传的工作。

    展开全文
  • 单独存储数据或单独接收组播数据都能达到要求(存得过来,也能保证丢包率稳定在允许范围内),但是边收边存就会导致丢包率猛增。 # 解决思路 在看过下面的博文后,得知磁盘IO操作频繁会导致CPU等待而不能及时...
  • UDP 丢包

    2015-07-06 16:11:17
    1、接收端处理时间过长导致丢包:调用recv方法接收端收到数据后,处理数据花了一些时间,处理完后再次调用recv方法,在这二次调用间隔里,发过来的包可能丢失。对于这种情况可以修改接收端,将包接收后存入一个缓冲区...
  • 1、接收端处理时间过长导致丢包:调用recv方法接收端收到数据后,处理数据花了一些时间,处理完后再次调用recv方法,在这二次调用间隔里,发过来的包可能丢失。对于这种情况可以修改接收端,将包接收后存入一个缓冲区...
  • udp服务器丢包

    2017-12-05 16:40:20
    1. udp客户端把注册的信息发往服务器,发现当数据包超过67个时,后面的数据包就收不到...5.发送频率太快:虽然每个的大小都小于mtu size 但是频率太快,例如40多个mut size的连续发送中间不sleep,也有可能导致
  • UDP组播丢包问题

    千次阅读 2018-04-13 19:23:44
    豁然开朗,UDP发送过快就是会导致丢包的,难怪我单步调试就不丢包。心累。源码如下 UDP丢包原因 一、主要丢包原因 1、接收端处理时间过长导致丢包:调用recv方法接收端收到数据后,处...
  • UDP丢包原因

    2013-06-07 17:20:33
    1、接收端处理时间过长导致丢包:调用recv方法接收端收到数据后,处理数据花了一些时间,处理完后再次调用recv方法,在这二次调用间隔里,发过来的包可能丢失。对于这种情况可以修改接收端,将包接收后存入一个缓冲区...
  • udp丢包问题

    2019-12-20 10:29:56
    1、接收端处理时间过长导致丢包:调用recv方法接收端收到数据后,处理数据花了一些时间,处理完后再次调用recv方法,在这二次调用间隔里,发过来的包可能丢失。对于这种情况可以修改接收端,将包接收后存入一个缓冲区...
  • 大神们好,小弟最近做了一个LINUX网卡驱动,用iperf来测试时候,发现UDP丢包。 用iperf测试UDP,一共测试两次,一次一个小时,速率为1000M,丢包率大概在0.0001%左右 再继续测试时,发现会大量丢包,已经惨不忍睹...
  • UDP丢包原因分析

    2018-07-15 15:05:13
    1.检测方法$ netstat -su2. 原因分析发送的数据包过大,超过以太网MTU值,这时UDP数据包会在...发送频率过高导致UDP内核发送缓冲区满,导致丢包接收应用程序处理数据过慢,UDP内核接收缓存区满,导致丢包。3.解...
  • UDP丢包的原因

    千次阅读 2015-06-08 16:00:01
    什么会导致udp丢包呢,我这里列举了如下几点原因: 1.调用recv方法接收端收到数据后,处理数据花了一些时间,处理完后再次调用recv方法,在这二次调用间隔里,发过来的包可能丢失。对于这种情况可以修改接收端,将...
  • udp丢包原因分析

    2020-01-06 11:15:20
    什么会导致udp丢包呢,这里列举了如下几点原因: 调用recv方法接收端收到数据后,处理数据花了一些时间,处理完后再次调用recv方法,在这二次调用间隔里,发过来的包可能丢失。对于这种情况可以修改接收端,将包...
  • udp丢包原因和解决

    千次阅读 2017-04-26 18:18:23
    一、主要丢包原因1、接收端处理时间过长导致丢包:调用recv方法接收端收到数据后,处理数据花了一些时间,处理完后再次调用recv方法,在这二次调用间隔里,发过来的包可能丢失。对于这种情况可以修改接收端,将包接收...
  • udp丢包分析》

    2020-04-22 10:35:56
    1、接收端处理时间过长导致丢包:调用recv方法接收端收到数据后,处理数据花了一些时间,处理完后再次调用recv方法,在这二次调用间隔里,发过来的包可能丢失。对于这种情况可以修改接收端,将包接收后存入一个缓冲区...
  • UDP主要丢包原因及具体问题分析

    千次阅读 2017-02-24 17:27:15
    一、主要丢包原因 1、接收端处理时间过长导致丢包:调用recv方法接收端收到数据后,处理数据花了一些时间,处理完后再次调用recv方法,在这二次调用间隔里,发过来的包可能丢失。对于这种情况可以修改接收端,将包...

空空如也

1 2 3 4
收藏数 63
精华内容 25
关键字:

udp发送导致接收丢包