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));

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),但是如果其中一个报文丢失,那么其他已收到的报文都无法返回给程序,也就无法得到完整的数据了。

--------------------------------------------------------------------------------

最近在研究linux下的UDP的传输,但是由于UDP协议本身的一些原因,在数据量非常大的时候会造成一定数量的丢包,数量越大,丢包率越高.

为了解决丢包这个问题,我从网上查到了一些资料,大致可以从三个方面来解决这个问题.

1. 从发送端解决(推荐)

适用条件: ①发送端是可以控制的.②微秒数量级的延迟可以接受.

解决方法:发送时使用usleep(1)延迟1微秒发送,即发送频率不要过快,延迟1微妙发送,可以很好的解决这个问题.

2.从接收端解决方法一

适用条件:①无法控制发送端发送数据的频率

解决方法: 用recvfrom函数收到数据之后尽快返回,进行下一次recvfrom,可以通过多线程+队列来解决.收到数据之后将数据放入队列中,另起一个线程去处理收到的数据.

3.从接收端解决方法二

适用条件:①使用方法2依然出现大规模丢包的情况,需要进一步优化

解决方法:使用setsockopt修改接收端的缓冲区大小,

  1. int rcv_size = 1024*1024; //1M

  2. int optlen=sizeof(rcv_size);

  3. int err=setsockopt(sock,SOL_SOCKET,SO_RCVBUF,(char *)&rcv_size,optlen);//设置好缓冲区大小


设置完毕可以通过

setsockopt(sock,SOL_SOCKET,SO_RCVBUF,(char *)&rcv_size,(socklen_t *)&optlen);

       来查看当前sock的缓冲区大小

但是,会发现查到的大小并不是1M而是256kb,后来发现原来是linux系统默认缓冲区大小为128kb,设置最大是这个的2倍

所以需要通过修改系统默认缓冲区大小来解决

使用root账户在命令行下输入: 

vi /etc/sysctl.conf

添加一行记录(1049576=1024*1024=1M)

net.core.rmem_max=1048576

保存之后输入

/sbin/sysctl -p

使修改的配置生效

此时可以通过 sysctl -a|grep rmem_max 来看配置是否生效. 

生效之后可以再次运行程序来getsockopt看缓冲区是否变大了,是否还会出现丢包现象了

楼主使用的是方法2+方法3 双管齐下,已经不会出现丢包现象了,如果还有不同程度的丢包 可以通过方法三种继续增加缓冲区大小的方式来解决

--------------------------------------------------------------------------------

UDP丢包

我们是后一个包丢掉了

最近在做一个项目,在这之前,做了个验证程序.
发现客户端连续发来1000个1024字节的包,服务器端出现了丢包现象.
纠其原因,是服务端在还未完全处理掉数据,客户端已经数据发送完毕且关闭了.

有没有成熟的解决方案来解决这个问题.
我用过sleep(1),暂时解决这个问题,但是这不是根本解决办法,如果数据量大而多,网络情况不太好的话,还是有可能丢失.

你试着用阻塞模式吧...
select...我开始的时候好像也遇到过..不过改为阻塞模式后就没这个问题了...

采用回包机制,每个发包必须收到回包后再发下一个

UDP丢包是正常现象,因为它是不安全的。

丢包的原因我想并不是“服务端在还未完全处理掉数据,客户端已经数据发送完毕且关闭了”,而是服务器端的socket接收缓存满了(udp没有流量控制,因此发送速度比接收速度快,很容易出现这种情况),然后系统就会将后来收到的包丢弃。你可以尝试用setsockopt()将接收缓存(SO_RCVBUF)加大看看能不能解决问题。

服务端采用多线程pthread接包处理

UDP是无连接的,面向消息的数据传输协议,与TCP相比,有两个致命的缺点,一是数据包容易丢失,二是数据包无序。
要实现文件的可靠传输,就必须在上层对数据丢包和乱序作特殊处理,必须要有要有丢包重发机制和超时机制。
常见的可靠传输算法有模拟TCP协议,重发请求(ARQ)协议,它又可分为连续ARQ协议、选择重发ARQ协议、滑动窗口协议等等。
如果只是小规模程序,也可以自己实现丢包处理,原理基本上就是给文件分块,每个数据包的头部添加一个唯一标识序号的ID值,当接收的包头部ID不是期望中的ID号,则判定丢包,将丢包ID发回服务端,服务器端接到丢包响应则重发丢失的数据包。
模拟TCP协议也相对简单,3次握手的思想对丢包处理很有帮助。

udp是不安全的,如果不加任何控制,不仅会丢失包,还可能收到包的顺序和发送包的顺序不一样。这个必须在自己程序中加以控制才行。
收到包后,要返回一个应答,如果发送端在一定时间内没有收到应答,则要重发。

UDP本来存在丢包现象,现在的解决方案暂时考虑双方增加握手.
这样做起来,就是UDP协议里面加上了TCP的实现方法.
程序中采用的是pthread处理,丢包率时大时小,不稳定可靠

我感觉原因可能有两个,一个是客户端发送过快,网络状况不好或者超过服务器接收速度,就会丢包。
第二个原因是服务器收到包后,还要进行一些处理,而这段时间客户端发送的包没有去收,造成丢包。

解决方法,一个是客户端降低发送速度,可以等待回包,或者加一些延迟。
二是,服务器部分单独开一个线程,去接收UDP数据,存放在一个缓冲区中,又另外的线程去处理收到的数据,尽量减少因为处理数据延时造成的丢包。

有两种方法解决楼主的问题:
方法一:重新设计一下协议,增加接收确认超时重发。(推荐)
方法二:在接收方,将通信和处理分开,增加个应用缓冲区;如果有需要增加接收socket的系统缓冲区。(本方法不能从根本解决问题,只能改善)

网络丢包,是再正常不过的了。
既然用UDP,就要接受丢包的现实,否则请用TCP。
如果必须使用UDP,而且丢包又是不能接受的,只好自己实现确认和重传,说白了,就是自己实现TCP(当然是部分和有限的简单实现)。

UDP是而向无连接的,用户在实施UDP编程时,必须制定上层的协议,包括流控制,简单的超时和重传机制,如果不要求是实时数据,我想TCP可能会更适合你!

-------------------------

1:什么是丢包率? 

你的电脑向目标发送一个数据包,如果对方没有收到.就叫丢包. 
比如你发10个,它只收到9个. 那么丢包率就是 10% 
数据在网络中是被分成一各个个数据报传输的,每个数据报中有表示数据信息和提供数据路由的桢.而数据报在一般介质中传播是总有一小部分由于两个终端的距离过大会丢失,而大部分数据包会到达目的终端.所谓网络丢包率是数据包丢失部分与所传数据包总数的比值.正常传输时网络丢包率应该控制在一定范围内.

2:什么是吞吐量?
网络中的数据是由一个个数据包组成,防火墙对每个数据包的处理要耗费资源。吞吐量是指在没有帧丢失的情况下,设备能够接受的最大速率。其测试方法是:在测试中以一定速率发送一定数量的帧,并计算待测设备传输的帧,如果发送的帧与接收的帧数量相等,那么就将发送速率提高并重新测试;如果接收帧少于发送帧则降低发送速率重新测试,直至得出最终结果。吞吐量测试结果以比特/秒或字节/秒表示。

吞吐量和报文转发率是关系防火墙应用的主要指标,一般采用FDT(Full Duplex Throughput)来衡量,指64字节数据包的全双工吞吐量,该指标既包括吞吐量指标也涵盖了报文转发率指标。 

随着Internet的日益普及,内部网用户访问Internet的需求在不断增加,一些企业也需要对外提供诸如WWW页面浏览、FTP文件传输、DNS域名解析等服务,这些因素会导致网络流量的急剧增加,而防火墙作为内外网之间的唯一数据通道,如果吞吐量太小,就会成为网络瓶颈,给整个网络的传输效率带来负面影响。因此,考察防火墙的吞吐能力有助于我们更好的评价其性能表现。这也是测量防火墙性能的重要指标。

吞吐量的大小主要由防火墙内网卡,及程序算法的效率决定,尤其是程序算法,会使防火墙系统进行大量运算,通信量大打折扣。因此,大多数防火墙虽号称100M防火墙,由于其算法依靠软件实现,通信量远远没有达到100M,实际只有10M-20M。纯硬件防火墙,由于采用硬件进行运算,因此吞吐量可以达到线性90-95M,是真正的100M防火墙。

对于中小型企业来讲,选择吞吐量为百兆级的防火墙即可满足需要,而对于电信、金融、保险等大公司大企业部门就需要采用吞吐量千兆级的防火墙产品。

3:检测丢包率
下载一个世纪前线,在百度可以找到,很小的程序。

NetIQ Chariot  一款网络应用软件性能测试工具

网络吞吐量测试,CHARIOT测试网络吞吐量

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/142903.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python【寻找缺失元素】

要求: 给定一个非负整数数组A,该数组的元素都是从1~N的元素组成,现在发现其中缺失一个,请找出这个缺失的元素 代码如下: def find_missing_element(arr):"""找出缺失的元素:param arr: 包含1~N之间的整数的数组&…

试论轮回的证据(欢迎讨论)

这几天看了几个鸟类筑巢的视频,十分惊叹。 一个鸟找个平台或树杈,用几个树枝搭个简陋的窝,这个确实是理所当然的事情,没什么奇怪的。 而有些鸟类的窝,十分的精巧,需要智商和技术。那么这些鸟类是怎么学会的…

jupyter lab配置列表清单

❤️觉得内容不错的话,欢迎点赞收藏加关注😊😊😊,后续会继续输入更多优质内容❤️ 👉有问题欢迎大家加关注私戳或者评论(包括但不限于NLP算法相关,linux学习相关,读研读博…

数据结构上机实验——图的实现(以无向邻接表为例)、图的深度优先搜索(DFS)、图的广度优先搜索(BFS)

文章目录 数据结构上机实验1.要求2.图的实现(以无向邻接表为例)2.1创建图2.1.1定义图的顶点、边及类定义2.1.2创建无向图和查找2.1.3插入边2.1.4打印函数 2.2图的深度优先搜索(DFS)2.3图的广度优先搜索(BFS&#xff09…

c/c++反汇编 | 逆向 | 初级小牛犊

c语言,难学不是没有道理的,不过能够更深层次了解底层,也不是没有理论支持的 之前简单的理解为,为什么C/C的程序能效率高?“应用层”我们写的屎山一样的代码,其实在编译的时候,编译器都会帮我们优…

Android的亮灯逻辑辨析

Android手机的亮灯逻辑由三层结构&#xff1a; 1. framework层控制行为逻辑 2. hardware提供HAL接口 3. 驱动层负责亮灯。 首先在/framework/base/core/res/res/values/config.xml中定义了灯的颜色和亮灯阈值 <!-- Display low battery warning when battery level dip…

竞赛 题目:垃圾邮件(短信)分类 算法实现 机器学习 深度学习 开题

文章目录 1 前言2 垃圾短信/邮件 分类算法 原理2.1 常用的分类器 - 贝叶斯分类器 3 数据集介绍4 数据预处理5 特征提取6 训练分类器7 综合测试结果8 其他模型方法9 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于机器学习的垃圾邮件分类 该项目…

技术贴 | SQL 执行 - 执行器优化

本期技术贴主要介绍查询执行引擎的优化。查询执行引擎负责将 SQL 优化器生成的执行计划进行解释&#xff0c;通过任务调度执行从存储引擎里面把数据读取出来&#xff0c;计算出结果集&#xff0c;然后返回给客户。 在关系型数据库发展的早期&#xff0c;受制于计算机 IO 能力的…

前端JS解构数组对象

// 3. 对象数组解构const arr [{username: 小明,age: 18,agw:19},{username: 小ha,age: 18,agw:19}]arr.map(item>item.age)//js结构数组对象console.log( arr.map(item>{return {aaa:item.age,bbb:item.username}}))

搜维尔科技:【软件篇】TechViz是一款专为工程设计的专业级3D可视化软件

在沉浸式房间内深入研究您自己的 3D 数据 沉浸式房间是一个交互式虚拟现实空间&#xff0c;其中每个表面&#xff08;墙壁、地板和天花板&#xff09;都充当投影屏幕&#xff0c;创造高度沉浸式的体验。这就像您的 3D 模型有一个窗口&#xff0c;您可以在其中从不同角度走动、…

bclinux aarch64 ceph 14.2.10 文件存储 Ceph File System, 需要部署mds: ceph-deploy mds

创建池 [rootceph-0 ~]# ceph osd pool create cephfs_data 64 pool cephfs_data created [rootceph-0 ~]# ceph osd pool create cephfs_metadata 32 pool cephfs_metadata created cephfs_metadata 64 报错 官方说明&#xff1a; 元数据池通常最多可容纳几 GB 的数据。为…

php使用正则表达式和翻译字典json文件做翻译

需求&#xff1a;把页面中的中文翻译成越南文。 思路&#xff1a;在框架渲染页面的地方&#xff08;这个地方能获取到页面渲染后的所有html数据&#xff0c;设为$str&#xff09;&#xff0c;使用以下方法。 //翻译中文 读取json文件&#xff0c;使用正则表达式替换中文 publi…

haproxy端口耗尽no free ports

用haproxy配置负载均衡时出现端口不足错误&#xff1b;后端服务连接一会高一会儿低&#xff0c;从0到1w、2w跳变&#xff1b;实际连接数为4w左右&#xff1b; haproxy[8765]: Connect() failed for backend 09e581: no free ports. 问题描述 在请求很少的时候&#xff0c;工作…

人工智能与大数据:驱动现代业务转型的双引擎

在当今数字化时代&#xff0c;人工智能&#xff08;AI&#xff09;和大数据已成为驱动业务和技术创新的关键力量。它们的结合不仅重塑了传统行业&#xff0c;也催生了新的商业模式和服务方式。 AI与大数据在零售行业的应用 在零售行业&#xff0c;AI和大数据的应用已经成为提…

排序 算法(第4版)

本博客参考算法&#xff08;第4版&#xff09;&#xff1a;算法&#xff08;第4版&#xff09; - LeetBook - 力扣&#xff08;LeetCode&#xff09;全球极客挚爱的技术成长平台 本文用Java实现相关算法。 我们关注的主要对象是重新排列数组元素的算法&#xff0c;其中每个元素…

No208.精选前端面试题,享受每天的挑战和学习

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…

echarts官网卡?

全网echarts案例资源大总结和echarts的高效使用技巧&#xff08;细节版&#xff09; - 掘金 drawnLine() {let myChart echarts.init(document.getElementById("grade"));// 绘制图表myChart.setOption({title: {left: "center",},tooltip: {trigger: &qu…

数字孪生智慧园区:大数据驱动下的运营管理革新

随着物联网、大数据、云计算等技术的飞速发展&#xff0c;数字孪生技术应运而生&#xff0c;它将物理世界与数字世界紧密连接起来&#xff0c;为各行各业提供了前所未有的解决方案。智慧园区作为城市的重要组成部分&#xff0c;通过数字孪生技术&#xff0c;可以实现更加高效、…

Redis键指令详解

文章目录 基础命令名称匹配过期时间 Redis系列&#xff1a;安装和初步使用 基础命令 键&#xff0c;即Key&#xff0c;是值的索引&#xff0c;如果翻译成钥匙会更容易理解一些&#xff0c;相当于打开数据的钥匙。或者从编程语言的角度出发&#xff0c;键就是变量名&#xff1…

spring cloud之服务通信

openfeign(*) 简介 官网&#xff1a;https://cloud.spring.io/spring-cloud-openfeign/reference/html/Feign是一个声明式的伪HTTP客户端(底层使用RestTemplate)&#xff0c;它使编写web服务客户端变得更容易。使用feign&#xff0c;只需要创建一个接口并对其添加注解。它具有…