Linux网络编程-UDP接收数据丢包解决方案

linux修改网络缓冲区大小 一、修改套接字socket的缓存大小 最小值 最大值 默认值 echo 65536 > /proc/sys/net/core/rmem_min echo 256960 > /proc/sys/net/core/wmem_max echo 65536 > /proc/sys/net/core/wmen_default 二、修改tcp接收/发送缓冲区 最小值 最大值 默认值 echo "4096 32768 65536" > /proc/sys/net/ipv4/tcp_rmem ec 阅读详情

转自 http://blog.youkuaiyun.com/baidu_35692628/article/details/76165337

序言

项目涉及基于UDP的socket通信,该部分的基本情况如下:


  • 发端程序:主函数开启4个发包线程,每个线程发送一定量的数据,通过限制发包速率限制发包流量。


  • 收端程序:主函数对应开启4个收包线程,每个线程收取对应端口的数据,收到数据包即时封装处理。


  • 其他说明:

    • 本地收发。如果不限制发包速率将会非常快

    • 基于UDP。使用recvfrom()函数收包

    • recvfrom()接收后立即将包加入队列并封装处理,即一次处理单个包

    • 发包流量最大160Mbps = 20MBps

    • 多种流量:160Mbps,80Mbps,40Mbps等进行测试


  • 测试方式: 
    • 发送一定时间的数据。 
      • 如设置发送1s,发送数据量160Mbits,即160Mbps流量
    • 收到数据包后进行包计数。 
      • 统计收包率/丢包率
    • 记录收端处理数据耗时,对比发端耗时。 
      • 即测试收端处理速度,不过应该注意此处的耗时只是处理所收到数据包的耗时,并不一定是所有数据量的耗时,如果存在丢包的话。


  • 但是现在测试出现的问题如下:

    • 收包率低/丢包率高。

      • 丢包率最高时可达67% 
        • 速率逐渐降低,收包率有上升趋势
        • 到一定速率,速率继续降低,收包数也不继续上升
    • 最大容量下耗时超过了发包耗时

      • 耗时最大可达发送时间的2倍以上 
        • 速率逐渐降低,耗时有减小趋势
        • 到一定速率,速率继续降低,由于只能处理一定收包数,耗时基本稳定


1. 问题分析


  • 收包率低/丢包率高的原因分析

    • (1) 缓存太小,不能及时接收数据。

      • 连续多个UDP包超过了UDP接收缓冲区大小 
        • 如:UDP包过大
        • 如:UDP发包速率过快,突发大数据流量超过了缓冲区上限
    • (2)recvfrom()接收到数据之后处理速度太慢

      • 如果数据接收和处理/渲染是连续进行的,那么可能由于数据处理过慢,两次recvfrom调用的时间间隔里发过来的包丢失


2. 问题验证和解决措施


  • (1) 缓存太小不能及时接收数据

    • [1] 分析:

      • UDP无需真正的发送缓冲区:

        • UDP是不可靠连接,不必保存应用进程的数据拷贝,因此无需真正的发送缓冲区(TCP需要)。应用进程的数据在沿协议栈往下传递,以某种形式拷贝到内核缓冲区,然而数据链路层在送出数据之后将丢弃该拷贝
      • UDP是没有流量控制的:

        • 较快的发送端可以很容易淹没较慢的接收端,导致接收端的UDP丢弃数据报。
        • UDP套接字的缓冲区是以一个个报文为单位进行排队的,调用一次recvfrom表示提取一个报文,和TCP基于字节流的方式是不同的
      • 因此,如果socket接收缓存设置过小,就会因为UDP包过大或者发包速率过快而丢包 


    • [2] 解决方法:重新设置UDP接收缓冲区大小

      • UDP接收缓冲区默认值:cat /proc/sys/net/core/rmem_default 
        • 本系统:212992 = 208K
      • UDP接收缓冲区最大值:cat /proc/sys/net/core/rmem_max,UDP最大可设置值的一半 
        • 本系统:212992 = 208K,即最大值425984 = 416K
      • UDP接收缓冲区最小值:sysctl -a | grep rmem

        • 本系统:net.ipv4.udp_rmem_min = 4096 = 2K,由内核的宏决定
      • UDP发送缓冲区默认值:cat /proc/sys/net/core/wmem_default

        • 本系统:212992 = 208K
      • UDP发送缓冲区最大值:cat /proc/sys/net/core/wmem_max 
        • 本系统:212992 = 208K,即最大值425984 = 416K
      • UDP发送缓冲区最小值:sysctl -a | grep wmem 
        • 本系统:net.ipv4.udp_wmem_min = 4096 = 2K,由内核的宏决定 

    • [3] 解决步骤:

      • 调整UDP缓冲区大小:使用函数setsockopt()函数修改接收缓冲区大小

        • 缓冲区改大可以处理突发的大流量数据,不至于数据(视音频等)变化、流量突然增大的时候缓冲区溢出
      • 或

      • 重新设置系统缓冲区最大值,再调整UDP缓冲区大小:

        • 打开配置文件:sudo vim /etc/sysctl.conf

        • 在文件末尾添加:net.core.rmem_max = 6291456

          • 将接收缓冲最大值设置为12582912 = 12M
        • 执行配置:sysctl -p

        • 重新查看最大值:cat /proc/sys/net/core/rmem_max

        • 发现系统接收缓冲最大值已改变,此时可以通过setsockopt函数设置更大接收缓存。发送缓冲最大值也可以通过类似方式修改:net.core.wmem_max = 6291456,sysctl -p

/* setsockopt()函数修改:*/

//函数原型
int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);

sockfd: 标识一个套接字的描述字
level: 选项定义的层次:支持SOL_SOCKET, IPPROTO_TCP, IPPROTO_IP,和IPPROTO_IPV6
optname:需设置得选项 SO_RCVBUF(接收缓冲区),SO_SNDBUF(发送缓冲区)
optval:指针,指向存放选项待设置的新值的缓冲区
optlen:optval的大小


//示例
int recv_size = 2 * 1024 * 1024;    //设置为4M
setsockopt(s,SOL_SOCKET, SO_RCVBUF, (const char *)&recv_size,sizeof(recv_size));  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15


  • (2)recvfrom()接收到数据之后处理速度太慢

    • [1] 分析:

      • UDP无需真正的缓冲区,不必保存应用进程的数据拷贝

        • 这就对数据处理的实时性提出了很高要求
      • recvfrom()接收速率并不是系统受限因素

        • recvfrom()处理速度是由CPU速度决定的(看到过这种说法,待验证),如果线程正常调用,几百Mbps的速度该函数肯定能跟上
      • 数据处理是速度受限因素之一

        • 程序在recvfrom接收到数据之后还进行了封装处理,即数据接收和数据处理是绑定的,处理速度跟不上接收速度(渲染速度跟不上socket接收速度)
      • 线程挂起再唤醒耗时受限速度之二

        • 尽管由CPU决定的recvfrom接收速度足够快,但如果接收数据线程从挂起再到唤醒接收数据,这个过程耗时可达数百毫秒 

    • [2] 解决方法:

      • 数据处理速度受限:数据接收和数据处理分离 
        • 接收数据单独存储,然后直接返回,保证recvfrom不丢数据或超时
        • 数据处理由其他函数或线程独立完成
      • 线程响应速度受限:保持线程一直在运行或监听状态 
        • 因为数据接收和处理函数都在同一线程,可将数据接收和处理从逻辑上分开
        • 如果不在统一线程,由于数据到了再起线程速度过慢,可考虑使用线程池技术 

    • [3] 解决步骤:

      • recvfrom和数据处理函数不再顺序执行一次只处理一个包。
      • 逻辑上分离数据接收和处理: 
        • recvfrom负责接收数据并存储,设置单独计数1
        • 数据处理函数负责从从存储中拿数据并处理,设置单独计数2
      • 抓包线程一直处于运行状态:while 
        • 数据处理可以等待唤醒
        • 但数据接收需要一直进行,否则难免丢包


补充:TCP缓冲区查看和修改命令

  • TCP接收缓冲区大小

    • TCP接收缓冲区默认值:cat /proc/sys/net/ipv4/tcp_rmem 
      • 本系统:87380,约85K
    • TCP接收缓冲区最大值:cat /proc/sys/net/core/rmem_max ,TCP最大可设置值的一半(与UDP同) 
      • 本系统:212992 = 208K,即最大值425984 = 416K。
      • 已被我修改为:3145728 = 3M,即最大值6291456 = 6M
    • TCP接收缓冲区最小值:sysctl -a | grep rmem 
      • 本系统:net.ipv4.udp_rmem_min = 4096 = 2K
    • 通用命令:cat /proc/sys/net/ipv4/tcp_rmem 
      • 4096 87380 6291456,依次为最小值、默认值、最大值
  • TCP接收缓冲区大小

    • TCP发送缓冲区默认值:cat /proc/sys/net/ipv4/tcp_wmem 
      • 本系统:16384 = 16K
    • TCP发送缓冲区最大值:cat /proc/sys/net/core/wmem_max,TCP最大可设置值的一半 
      • 本系统:212992 = 208K,即最大值425984 = 416K
    • TCP发送缓冲区最小值:sysctl -a | grep wmem 
      • 本系统:net.ipv4.udp_wmem_min = 4096 = 2K
    • 通用命令:cat /proc/sys/net/ipv4/tcp_wmem 
      • 4096 16384 4194304,依次为最小值、默认值、最大值

    注:通过cat /proc/sys/net/ipv4/tcp_wmem命令和cat /proc/sys/net/core/wmem_max命令得出的TCP发送缓冲区最大值不一致,我觉得应该以cat /proc/sys/net/ipv4/tcp_wmem为准,即最大值为4M。



Acknowledgements: 
http://blog.youkuaiyun.com/getnextwindow/article/details/24328117?utm_source=tuicool&utm_medium=referral  
http://blog.youkuaiyun.com/ljh0302/article/details/49738191  
http://blog.youkuaiyun.com/herecles/article/details/8146017  
http://blog.sina.com.cn/s/blog_858820890100sfpx.html  
http://bbs.youkuaiyun.com/topics/390958727

2017.07.29 
文中错误和不足部分,欢迎交流指正


1) UDP Packet Lost - receive buffer errors 最近公司项目遇到一个 UDP丢包问题,导致数据库有一些异常。 在经历了几天加几个夜晚的分析定位,总算将问题解决,特写下总结、分析的文章,以供追溯 一. UDP Receive Packet 过程 首先网络报文通过物理网线发送到网卡 网络驱动程序会把网络中的报文读出来放到 ring buffer 中,这个过程使用 DMA(Direct Memory Access),不需要 CP... 阅读详情

相关推荐

UDP服务端丢包-发送频率过高导致丢包

接收方丢UDP包,发送频率过高导致丢包,主要会造成接收方自身丢包。

西京刀客 2396

UDP丢包

3. 设置套接字选项:可以使用`setsockopt`函数设置一些套接字选项来优化UDP传输,例如设置`SO_REUSEADDR`选项来允许地址重用,设置`SO_RCVTIMEO`选项来设置接收超时时间等。尽管你可以采取上述措施来减少UDP丢包的概率,但是由于UDP的特性,无法完全消除丢包的可能性。例如,在发送数据时,要求接收方发送确认消息,以确保数据的完整性和正确性。如果你对数据包的可靠性要求较高,可以考虑使用可靠的网络连接,如TCP。

noSimBa的博客 4454

Linux网络编程:TCP与UDP详解

本文深入探讨了Linux网络编程中的TCP和UDP协议,包括它们的基本概念、使用方法和通信过程。文章通过示例代码、时序图和异常情况处理,帮助读者全面理解TCP和UDP在服务器编程中的应用。

陆业聪 1954

【Linux】UDP 网络编程

UDP 的使用比较格式化,首先先套接字,接着进行(一般客户端不需要绑定),然后进行,最后套接字。

2401_86449430的博客 1万+

Linux网络编程——UDP Socket

UDP socket编程的知识点总结 Udp是无连接的、不可靠的传输协议,面向消息的数据传输协议 与TCP相比,有两个致命的缺点,一是数据包容易丢失,二是数据包无序 建立在udp上层的协议,需要自己定义流控制、超时、重传等。 进行udp传输有两个问题,一个是数据包大小,一个是发数据时间间隔,这两个因素是发送端影响udp丢包率的主要因素,而丢包率直接影响了传输效率 UDP没有真正的发送缓冲区,因为它是不可靠无连接的,不需要保存应用进程的数据备份,应用进程的数据沿着协议栈往下传递,拷贝到内核...

Xinyue_Lu的博客 1041

Oracle EBS财务模块(三)总账功能

(一)总账管理系统主要功能  总账管理系统(Oraclegeneralledger)是一个公司一切账务系统的核心,它好比是公司会计信息的中央处理器。总账管理系统提供了一个完整的财务管理核算及分析流程。它是所有子账户的信息存储器,因此反映了所有子账户的财务和现金活动。总账管理系统的主要作用是记录公司的财务活动,并生成财务报表和管理报表,以帮助公司内外人士进行决策。一个公司或组织的制造系统、项目管理系

苏南生的优快云博客 2万+

【Linux】socket网络编程之UDP

udp网络套接字编程,实现了一个客户端可以通过指令操控服务器,然后将服务器应该输出的结果打印到客户端

s_little_monster的博客 1万+

GPS定位不准?可能是GDOP在作怪!手把手教你优化卫星几何分布

本文深入解析了GPS定位精度不佳的常见原因——几何精度因子GDOP。通过剖析卫星几何分布对定位误差的放大效应,文章提供了从理解GDOP、PDOP、HDOP等关键指标,到使用专业APP实时诊断卫星天空图,再到利用在线工具提前规划最佳定位时机的完整实战指南。旨在帮助户外爱好者、无人机飞手及专业用户主动优化卫星几何条件,从而显著提升定位可靠性。

weixin_29062823的博客 306

【Linux网络】Linux网络编程套接字,UDP与TCP

在当今这个信息技术日新月异的时代,网络编程已成为连接世界、构建各类互联网应用不可或缺的一部分。而Linux,作为开源操作系统的典范,其强大的网络功能和灵活性,为开发者们提供了一个广阔而深入的实践平台。在众多网络编程技术中,套接字(Socket)编程无疑是核心与基石,它不仅支撑着Web服务、即时通讯、在线游戏等日常应用,还是实现分布式系统、云计算服务的关键技术之一。

EterNity_TiMe_的计算机学习之路 5619

Ta-Lib源码解析(三):蜡烛图指标 (Candlestick Indicator) #(附Python重构代码和示意图)(补充中)

蜡烛图指标为识别K线形态的指标,笔者认为重点在于定义方式所提供的思路,背后的投资逻辑可以借鉴但不建议直接参考文档的翻译内容和源码逻辑存在不一致的现象,笔者分别列出中文百科中的定义和源码实际逻辑,供大家参考技术分析理论中的一些模糊词,ta-lib中给出了精确的定义源码

量化就是探索生活 3254

新能源知识库(68)复叠压缩式热泵蒸汽系统介绍

复叠压缩式热泵蒸汽系统通过多级压缩技术将低品位热能转化为高品位蒸汽,在汽车电镀场景中实现了高效、精准的能源利用。随着超高温工质与智能联供系统的发展,该技术将深度赋能电镀行业的高质量可持续发展。​:±1℃控温保障镀层均匀性,提升产品良率;多台复叠热泵+储热装置(如纺织厂6台热泵)复叠热泵+余热回收+智能控制(化工厂案例)​:无燃烧设计契合汽车行业ESG目标。单台高温热泵机组(如92P型号)复叠压缩式热泵蒸汽系统以。67.4万元(↓22%)600万–1200万元。事故率 ↓90%​​。150万–600万元。

竹君子之家 1421

Linux网络编程 ——UDP 通信

Linux网络编程 ——UDP 通信 1. UDP 1.1 UDP 通信 1.2 广播 1.3 组播(多播) 2. 本地套接字

weixin_43412762的博客 3145

29、高速低功耗采样保持放大器设计

本文详细介绍了适用于低功耗模数转换器的高速低电压采样保持放大器(SHA)的设计技术,包括传统SHA的局限性、采样技术分类以及全NPN型和BiCMOS型SHA的具体设计实现。同时,文章深入探讨了优化输入电容、采样开关驱动及低功耗设计等具体措施,并提供了10位ADC前端和无线通信应用中的实例分析,为相关领域的工程师提供有价值的参考。

weixin_30600615的博客 425

Linux网络编程系列之UDP广播

Linux网络编程系列之UDP广播,UPD广播的简单介绍和使用

AABond的博客 3770

OpenClaw 源代码深度分析报告 &如何把企业自有的MCP server 工具集成到OpenClaw里? 怎样通过OpenAI 风格SDK 解析出来OpenClaw的全部的流式输出内容?

项目属性详情名称OpenClaw版本2026.3.2许可证MIT语言最低运行时包管理器pnpm主要仓库},// 注册工具// 工具实现},});// 注册命令" }),});},方面评价模块化设计⭐⭐⭐⭐⭐ 插件架构清晰,扩展性强协议设计⭐⭐⭐⭐⭐ WebSocket 协议完善,支持多种客户端多渠道支持⭐⭐⭐⭐⭐ 20+ 消息通道,覆盖主流平台安全机制⭐⭐⭐⭐ 配对认证、设备签名、权限控制完善本地优先⭐⭐⭐⭐⭐ 数据本地存储,用户完全控制项目属性详情名称OpenClaw版本。

AI天才研究院 941

Python爬虫实战:基于Playwright与异步技术的专利数据抓取系统

专利数据是企业技术创新、市场竞争分析和行业趋势预测的关键情报来源。然而,专利数据通常分散在各个国家的专利局网站,数据结构复杂,反爬机制严格,使得高效抓取成为技术挑战。本文将详细介绍如何构建一个基于最新Python技术的专利数据抓取系统,涵盖Selenium的现代化替代方案Playwright、异步编程、智能代理轮换等高级技术。

2201_76125261的博客 1562

Linux网络编程系列之UDP组播

Linux网络编程系列之UDP组播,UDP组播的简单介绍和使用

AABond的博客 4507

【AI智能体】基于OpenCode 搭建Skills环境与项目实战开发详解

基于OpenCode 搭建Skills环境与项目实战开发详解

congge 8901

UDP丢包(Linux)并测试

一、UDP丢包现象 UDP丢包是正常现象,因为它是不安全的。 UDP是无连接的,面向消息的数据传输协议,与TCP相比,有两个致命的缺点,一是数据包容易丢失,二是数据包无序。 要实现文件的可靠传输,就必须在上层对数据丢包和乱序作特殊处理,必须要有要有丢包重发机制和超时机制。 常见的可靠传输算法有模拟TCP协议,重发请求(ARQ)协议,它又可分为连续ARQ协议、选择重发ARQ协议、滑动窗口协议...

yx20130919的博客 4264

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

网络编程——UDP

Linux下的UDP网络编程通过 socket()、sendto() 和 recvfrom() 等系统调用实现数据发送和接收。接收数据:服务器通过 recvfrom() 接收客户端发送的数据,recvfrom() 可以返回发送数据的客户端地址信息。创建套接字:使用 socket() 创建UDP套接字,指定地址族 AF_INET 和套接字类型 SOCK_DGRAM。无连接特性:UDP是无连接的,这意味着客户端和服务器不需要建立连接,只要有目标地址和端口,数据就可以发送。1.使用 sendto() 发送数据。

WWWWwwwBJ的博客 2064

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

《Linux 网络编程二:UDP 与 TCP 的差异、应用及问题应对》

本文对比了UDP和TCP协议的主要特性。UDP是无连接协议,面向数据包传输,具有实时性高、机制简单等特点,但可靠性较差,适用于视频/音频流等场景。TCP是面向连接的可靠传输协议,通过三次握手建立连接,采用流式传输,确保数据完整性和顺序性,适用于文件传输等要求准确性的场景。文章还详细介绍了UDP丢包原因及解决方法、TCP的编程流程和函数接口,以及TCP粘包问题及其解决方案。两种协议各具特点,应根据具体应用场景选择合适的传输协议。

weixin_72612809的博客 1089

【Linux网络编程】传输协议UDP

【Linux网络编程】传输协议UDP

Giggins GaoBlog 3395

Linux:网络编程套接字及UDP

问题1:在进行网络通信的时候,是不是我们的两台机器在进行通信呢??——>思考一下我们打开qq软件,他属于应用层,完成了数据的发送和接受……

weixin_51142926的博客 5744
上一篇: 使用 iPerf 测试并排查 UDP 丢包问题
下一篇: ifconfig 下面的一些字段(errors, dropped, overruns)
简单并快乐着
博客等级 码龄15年 473粉丝 96原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值