QUdpSocket的readyRead信号触发时机解析

1.QUdpSocket的readyRead信号发送的时机

QUdpSocketreadyRead()信号是在有新的 UDP 数据报到达套接字的接收缓冲区,并且应用程序尚未读取这些数据时发出的。

具体来说,其触发时机如下:


✅ 触发条件

  1. UDP 数据报已到达本地主机并被操作系统接收;
  2. 该数据报已被放入QUdpSocket的内部接收缓冲区中
  3. 当前没有正在进行的readDatagram()(或类似读取操作),即事件循环处于空闲状态;
  4. 事件循环正在运行(例如调用了QApplication::exec()QEventLoop::exec()),因为readyRead()是通过 Qt 的事件系统异步发出的。

⚠️ 注意事项

  • readyRead()不会为每个数据报单独触发一次。如果多个数据报在事件循环处理前到达,它们会堆积在缓冲区中,readyRead()只触发一次,你需要在槽函数中循环读取所有可用的数据报,直到pendingDatagramSize() == -1

    示例:

    void onReadyRead() { while (udpSocket->hasPendingDatagram()) { QByteArray datagram; datagram.resize(udpSocket->pendingDatagramSize()); udpSocket->readDatagram(datagram.data(), datagram.size()); // 处理 datagram } }
  • 如果你在readyRead()信号的槽函数中没有读完所有数据,不会再发出新的readyRead()信号,直到下一批新数据到来(因为 Qt 认为已有未处理的数据,无需重复通知)。

  • readyRead()是一个“提示”信号,表示“现在可以无阻塞地读取数据”,不是“每来一个包就通知一次”。

  • UDP 是无连接、不可靠协议,数据报可能丢失、乱序或重复,但readyRead()只关心“有没有可读的数据”,不保证完整性或顺序。


🔄 与 TCP (QTcpSocket) 的区别

  • QTcpSocket::readyRead()表示有字节流可读,而QUdpSocket::readyRead()表示有完整数据报可读。
  • UDP 的每次readDatagram()读取的是一个完整的数据报,不会出现“半包”问题(但可能因缓冲区太小而截断)。

总结

QUdpSocket::readyRead()至少有一个完整的 UDP 数据报已到达且尚未被读取,并且事件循环有机会处理 I/O 事件时被触发。

确保在槽函数中用while(hasPendingDatagram())循环读取全部数据,避免遗漏。

2.readDatagram接口每次读取的是一个包吗

是的,QUdpSocket::readDatagram()每次调用读取的是一个完整的 UDP 数据报(即一个“包”)


✅ 核心行为说明:

  • UDP 是面向数据报(datagram-oriented)的协议,每个发送操作(如writeDatagram())对应一个独立的数据报。
  • 接收端每次调用readDatagram()原子地读取一个完整的数据报,不会出现“半包”或“粘包”(这是与 TCP 的关键区别)。
  • 即使你传入的缓冲区比实际数据报大,也只会读取当前这一个数据报的内容;如果缓冲区太小,则多余部分会被丢弃(UDP 不支持截断后保留剩余数据)。

📌 函数原型

qint64 readDatagram(char *data, qint64 maxSize, QHostAddress *address = nullptr, quint16 *port = nullptr);
  • data:用于存放接收到的数据报内容。
  • maxSize:缓冲区大小。必须 ≥ 当前待读数据报的实际大小,否则数据会被截断(且无法恢复)。
  • 可选参数addressport可获取发送方的地址和端口。

🔍 如何确保不丢数据?

  1. 先查询待读数据报的大小

    qint64 size = udpSocket->pendingDatagramSize();

    这个值就是下一个完整 UDP 包的字节数

  2. 分配足够缓冲区再读取

    QByteArray datagram; datagram.resize(udpSocket->pendingDatagramSize()); udpSocket->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);
  3. 循环读取所有待处理数据报(因为readyRead()可能对应多个包):

    while (udpSocket->hasPendingDatagram()) { // 读取一个完整包 }

⚠️ 注意事项

  • UDP 数据报最大理论长度为 65507 字节(IPv4 下:65535 - IP头20 - UDP头8),但实际受网络 MTU 限制(通常 ≤ 1500 字节)。若应用可能收大包,需确保缓冲区足够。
  • 如果maxSize < pendingDatagramSize()超出部分会被静默丢弃,且无法得知是否发生截断(除非你对比readDatagram()返回值与pendingDatagramSize())。
  • 每次readDatagram()调用只消耗接收队列中的一个数据报。

✅ 总结

readDatagram()每次读取且仅读取一个完整的 UDP 数据报,这是由 UDP 协议本身的“消息边界保留”特性决定的。正确使用pendingDatagramSize()配合循环读取,可安全高效地处理所有到达的数据包。

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

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

相关文章

学习日记day59

Day59_0116专注时间&#xff1a;目标是&#xff1a;5h30~6h。实际&#xff1a;4h31min每日任务&#xff1a;饭后的休息&#xff08;25min&#xff09;&#xff0c;学习间歇的休息&#xff08;15min&#xff09;都用手表计时器来监督40min二刷1道力扣hot100昨天的题再做一遍(如果…

2026 爆款多渠道语音机器人,大模型赋能自然交互 - 速递信息

智能语音交互成为企业“降本增效”的关键引擎 面对日益增长的客户咨询压力与服务体验挑战,大型企业正加速向智能化、自动化转型。传统语音机器人依赖关键词匹配与固定话术,难以应对复杂、个性化的交互需求,导致客户…

我们的阿克赛钦有多重要性?

阿克赛钦&#xff0c;这片位于中国新疆与西藏交界处、面积约 3 万平方公里的土地&#xff0c;是中国不可分割的领土&#xff0c;其战略与地缘价值至关重要。 从地理格局看&#xff0c;阿克赛钦是连接中国新疆与西藏的关键通道。 它处于帕米尔高原东麓&#xff0c;是新藏公路&…

第2章:SpringBoot开发规范

文章目录第2章&#xff1a;SpringBoot开发规范静态资源访问启动类位置常见形式启动方式讲解和部署第2章&#xff1a;SpringBoot开发规范 静态资源访问 默认静态资源位置 SpringBoot 会自动扫描以下目录中的静态资源&#xff0c;可直接通过 URL 访问&#xff1a; classpath:/…

2026全屋净水厂家权威推荐榜单:中央净水/管道净水/中央净水机/大流量净水器/除氯净水器/源头厂家精选。 - 品牌推荐官

在全屋净水领域,邦登净水(福建)有限公司凭借其技术实力与市场口碑,成为消费者关注的焦点。作为美国水世界集团旗下轻奢全屋净水品牌“BANG.D”在亚太地区的运营总部,邦登净水自2013年进入中国市场以来,已在中国厦…

UDP高并发优化:监控RcvbufErrors

你说得非常对&#xff01;在部署高并发 UDP 服务时&#xff0c;监控 RcvbufErrors 是一个关键的诊断手段。这个指标直接反映了内核因为接收缓冲区满而丢弃的 UDP 数据包数量——这是高吞吐 UDP 服务中最常见的性能瓶颈之一。&#x1f50d; 为什么关注 RcvbufErrors&#xff1f;…

强烈安利!专科生必用TOP8 AI论文网站测评

强烈安利&#xff01;专科生必用TOP8 AI论文网站测评 2026年专科生必备AI论文工具测评指南 在当前高等教育不断发展的背景下&#xff0c;专科生的学术写作需求日益增长&#xff0c;尤其是在论文撰写、文献检索和格式规范等方面面临诸多挑战。为了帮助广大专科生更高效地完成学术…

河南与江苏仅“咫尺之隔”,却因安徽没接壤

在中国的省级行政区版图里&#xff0c;河南与江苏是一对 “特殊邻居”—— 二者并未直接接壤&#xff0c;却在地理空间上形成了仅 18 公里的 “咫尺之隔”。 这一独特的距离&#xff0c;藏在河南、江苏与安徽的交界地带&#xff1a;从河南最东部的永城市&#xff0c;到江苏最西…

学习日记day58

Day58_0115专注时间&#xff1a;目标是&#xff1a;5h30~6h。实际&#xff1a;6h10min每日任务&#xff1a;饭后的休息&#xff08;25min&#xff09;&#xff0c;学习间歇的休息&#xff08;15min&#xff09;都用手表计时器来监督40min二刷1道力扣hot100昨天的题再做一遍(如果…

古代地名如此动听,却为何几乎都被改掉了?

西海、西夏、云梦泽、苍梧、风陵渡、九原、宁古塔、琅琊、金陵、奉天&#xff0c;一个个如此动听的古地名&#xff0c;为什么几乎都被改变或消失了&#xff1f; 其实&#xff0c;许多改变并非为“改”而改&#xff0c;而是社会发展的必然结果。 其一&#xff0c;为“避讳”。…

linux 如何查看udp协议缓冲区的默认大小

在 Linux 系统中&#xff0c;UDP 协议的接收和发送缓冲区大小可以通过内核参数进行配置。要查看 UDP 缓冲区的默认大小&#xff08;即未显式设置时的初始值&#xff09;以及最大限制&#xff0c;可以使用以下方法&#xff1a;1. 查看系统级别的 UDP 缓冲区默认值和限制这些值由…

从混沌到秩序:Lisp家族的演化与ANSI标准化的必然

从混沌到秩序&#xff1a;Lisp家族的演化与ANSI标准化的必然 1.1.1 Lisp的基因溯源&#xff1a;从λ演算到符号计算革命 Lisp的诞生可以追溯到1958年&#xff0c;由John McCarthy在MIT发明。其核心灵感来源于Alonzo Church的λ演算&#xff0c;这一数学模型构成了现代函数式编程…

【AI大模型开发】-基于FAISS的语义搜索系统(实战)

向量数据库实战&#xff1a;基于FAISS的语义搜索系统 一、项目概述 1.1 什么是向量数据库&#xff1f; 向量数据库是一种专门用于存储、索引和检索高维向量数据的数据库系统。在AI领域&#xff0c;向量通常是指通过预训练模型&#xff08;如Transformer&#xff09;将文本、图像…

2024年12月GESP真题及题解(C++八级): 排队

2024年12月GESP真题及题解(C八级): 排队 题目描述 小杨所在班级共有 nnn 位同学&#xff0c;依次以 1,2,…,n1,2,\dots,n1,2,…,n 标号。这 nnn 位同学想排成一行队伍&#xff0c;其中有些同学之间关系非常好&#xff0c;在队伍里需要排在相邻的位置。具体来说&#xff0c;有 …

2024年12月GESP真题及题解(C++八级): 树上移动

2024年12月GESP真题及题解(C八级): 树上移动 题目描述 小杨有一棵包含 nnn 个节点的树&#xff0c;其中节点的编号从 111 到 nnn&#xff0c;每个节点的颜色要么是白色要么是黑色&#xff0c;小杨可以任意选择节点 sss 和节点 ttt 并从节点 sss 出发移动到节点 ttt&#xff0c…

基于STM32单片机智能环境监控温湿度CO2光照PM2.5无线设计26-029

26-029、STM32智能环境监控系统设计-TFT1.44-PM2.5-CO2-BH1750-DHT11-WIFI-风扇本设计由STM32F103C8T6单片机核心板电路TFT1.44寸液晶电路PM2.5传感器电路CO2传感器电路BH1750光照检测电路DHT11温湿度传感器电路2路风扇电路WiFi-ESP8266模块电路电源电路组成。1、TFT1.44寸液晶…

基于STM32单片机智能炉温温度PID控制系统设计DIY21-615

本设计由STM32F103C8T6单片机核心板电路DS18B20防水型温度检测电路LCD1602液晶显示电路按键电路AO4405-MOS管驱动发热电阻电路组成。1、LCD1602液晶实时显示温度和温度阈值。2、如果当前温度低于温度阈值&#xff0c;则发热电阻启动加热&#xff0c;否则发热电阻断开&#xff0…

深度测评MBA必备AI论文网站TOP10:开题报告与文献综述全解析

深度测评MBA必备AI论文网站TOP10&#xff1a;开题报告与文献综述全解析 2026年MBA学术写作工具测评&#xff1a;为何需要一份权威榜单 随着AI技术在学术领域的深入应用&#xff0c;越来越多的MBA学生开始依赖智能写作工具提升论文效率。然而&#xff0c;面对市场上琳琅满目的平…

基于STM32单片机共享无线充电锂电池充电宝系统设计DIY21-640

本系统由STM32F103C8T6单片机核心板、继电器控制、蓝牙控制及电源组成。1、手机连接蓝牙设备。2、设备上贴有二维码&#xff0c;通过手机可以扫描&#xff0c;如果二维码解析正确&#xff0c;可以控制打开共享设备的继电器。3、如果使用完需要关闭设备开关&#xff08;即继电器…

LangGraph 科技详解:基于图结构的 AI 工作流与多智能体编排框架

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …