QT中UDP之UDPsocket通讯

目录

UDP:

举例:

服务器端:

客户端:

使用示例:

错误例子并且改正:


UDP:

(User Datagram Protocol即用户数据报协议)是一个轻量级的,不可靠的,面向数据报的无连接
协议。在网络质量令人十分不满意的环境下,UDP协议数据包丢失严重。由于UDP的特性:它不属于连
接型协议,因而具有资源消耗小,处理速度快的优点,所以通常音频、视频和普通数据在传送时使用
UDP较多,因为它们即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。所以QQ这种对保密
要求并不太高的聊天程序就是使用的UDP协议。
在Qt中提供了QUdpSocket 类来进行UDP数据报(datagrams)的发送和接收。Socket简单地说,就是
一个IP地址加一个port端口 。
流程:①创建QUdpSocket套接字对象 ②如果需要接收数据,必须绑定端口 ③发送数据用
writeDatagram,接收数据用 readDatagram 。

举例:

  1. 导入必要的头文件:

#include <QUdpSocket>

  1. 创建UDP套接字:

QUdpSocket *udpSocket = new QUdpSocket(this);

  1. 绑定本地端口(可选): 通常,UDP套接字不需要绑定到特定的本地端口,而是通过writeDatagram()函数直接指定目标IP地址和端口。但如果需要从特定的本地端口接收数据,可以进行绑定:

udpSocket->bind(localPort, QUdpSocket::ShareAddress);

  1. 发送数据: 使用writeDatagram()函数发送数据包到目标地址和端口:

QHostAddress targetAddress("192.168.0.100"); // 目标IP地址 quint16 targetPort = 1234; // 目标端口 QByteArray data = "Hello, UDP!"; // 要发送的数据 udpSocket->writeDatagram(data, targetAddress, targetPort);

  1. 接收数据: 为了接收数据,我们需要连接readyRead信号到一个槽函数,并在槽函数中读取数据:

connect(udpSocket, &QUdpSocket::readyRead, this, &MyClass::readPendingDatagrams);

然后在槽函数readPendingDatagrams()中处理接收到的数据:

void MyClass::readPendingDatagrams() { while (udpSocket->hasPendingDatagrams()) { QByteArray datagram; datagram.resize(udpSocket->pendingDatagramSize()); udpSocket->readDatagram(datagram.data(), datagram.size()); // 在这里处理接收到的数据 // ... } }

这样,你就可以使用UDP套接字在Qt中进行简单的UDP通信了。

示例说明: 假设我们有两个Qt应用程序,一个作为UDP服务器,另一个作为UDP客户端。服务器监听特定端口接收来自客户端的消息,并将消息原样发送回客户端。

服务器端:

#include <QTcpServer>
#include <QTcpSocket>class Server : public QObject
{Q_OBJECTpublic:Server(QObject *parent = nullptr) : QObject(parent){udpSocket = new QUdpSocket(this);udpSocket->bind(QHostAddress::Any, 1234);connect(udpSocket, &QUdpSocket::readyRead, this, &Server::readPendingDatagrams);}private slots:void readPendingDatagrams(){while (udpSocket->hasPendingDatagrams()) {QByteArray datagram;datagram.resize(udpSocket->pendingDatagramSize());udpSocket->readDatagram(datagram.data(), datagram.size());// 将接收到的数据原样发送回客户端udpSocket->writeDatagram(datagram, QHostAddress::LocalHost, 5678);}}private:QUdpSocket *udpSocket;
};

客户端:

#include <QTcpSocket>class Client : public QObject
{Q_OBJECTpublic:Client(QObject *parent = nullptr) : QObject(parent){udpSocket = new QUdpSocket(this);}void sendMessage(const QByteArray &message){udpSocket->writeDatagram(message, QHostAddress::LocalHost, 1234);}private:QUdpSocket *udpSocket;
};

使用示例:

// 在服务器端创建服务器对象
Server server;// 在客户端创建客户端对象
Client client;// 客户端发送消息给服务器
client.sendMessage("Hello, server!");// 服务器会将消息原样发送回客户端// 可以在客户端的槽函数中处理接收到的消息

以上示例演示了简单的UDP通信过程,在实际应用中,你可以根据需要进行更复杂的数据处理和错误处理。

错误例子并且改正:

在UDP通信中,一些常见的错误例子可能包括:

错误1:未绑定本地端口 在使用QUdpSocket时,如果忘记将UDP套接字绑定到本地端口,可能会导致数据无法正确发送或接收。

错误示例:

QUdpSocket *udpSocket = new QUdpSocket(this); udpSocket->writeDatagram("Hello, UDP!", QHostAddress::LocalHost, 1234);

改正方法: 确保在发送或接收数据前,先将UDP套接字绑定到本地端口。

QUdpSocket *udpSocket = new QUdpSocket(this); udpSocket->bind(QHostAddress::Any, 5678); // 绑定本地端口 udpSocket->writeDatagram("Hello, UDP!", QHostAddress::LocalHost, 1234);

错误2:接收数据时未处理所有数据报 在UDP通信中,可能会有多个数据报同时到达,如果只处理其中一个数据报,可能会导致其他数据报被丢弃。

错误示例:

void MyClass::readPendingDatagrams() { QByteArray datagram; datagram.resize(udpSocket->pendingDatagramSize()); udpSocket->readDatagram(datagram.data(), datagram.size()); // 处理接收到的数据(仅处理一个数据报) // ... }

改正方法: 使用循环处理所有待处理的数据报。

void MyClass::readPendingDatagrams() { while (udpSocket->hasPendingDatagrams()) { QByteArray datagram; datagram.resize(udpSocket->pendingDatagramSize()); udpSocket->readDatagram(datagram.data(), datagram.size()); // 处理接收到的数据(处理所有数据报) // ... } }

错误3:接收数据时未正确处理数据大小 当接收到的数据大小超过pendingDatagramSize()返回的值时,可能会导致数据截断。

错误示例:

void MyClass::readPendingDatagrams() { while (udpSocket->hasPendingDatagrams()) { QByteArray datagram; // 问题:未正确处理数据大小,导致截断 datagram.resize(udpSocket->pendingDatagramSize()); udpSocket->readDatagram(datagram.data(), datagram.size()); // 处理接收到的数据 // ... } }

改正方法: 在读取数据之前,先获取实际接收到的数据大小,并根据该大小调整数组大小。

void MyClass::readPendingDatagrams() { while (udpSocket->hasPendingDatagrams()) { QByteArray datagram; datagram.resize(udpSocket->pendingDatagramSize()); // 获取实际接收到的数据大小,并根据该大小调整数组大小 qint64 bytesRead = udpSocket->readDatagram(datagram.data(), datagram.size()); // 处理接收到的数据 // 注意:如果需要使用`bytesRead`来截取datagram的有效部分,确保不使用未读取部分。 // ... } }

这些是一些常见的错误例子和相应的改正方法。通过注意这些细节,可以更好地编写稳定和可靠的UDP通信代码。

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

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

相关文章

Emacs之实现鼠标/键盘选中即拷贝外界内容(一百二十)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

C++复刻:[流光按钮]+[悬浮波纹按钮]

目录 参考效果实现main.cppdialog.hdialog.cppflowingRayButton.h 流动光线按钮flowingRayButton.cpp 流动光线按钮hoveringRippleButton.h 悬浮波纹按钮hoveringRippleButton.cpp 悬浮波纹按钮模糊知识点 源码 参考 GitHub地址 B站主页 效果 实现 main.cpp #include "…

RN 设置背景图片(使用ImageBackground组件)

在RN版本0.46版本的时候添加了ImageBackground控件。ImageBackground可以设置背景图片&#xff0c;使用方法和image一样&#xff0c;里面嵌套了其他的组件 import React from "react"; import { ImageBackground, StyleSheet, Text, View } from "react-native…

设计模式-中介者模式在Java中使用示例-客户信息管理

场景 欲开发客户信息管理窗口界面&#xff0c;界面组件之间存在较为复杂的交互关系&#xff1a;如果删除一个客户&#xff0c; 要在客户列表(List)中删掉对应的项&#xff0c;客户选择组合框(ComboBox)中客户名称也将减少一个&#xff1b; 如果增加一个客户信息&#xff0c;…

go web框架 gin-gonic源码解读01————Engine

go web框架 gin-gonic源码解读01————Engine gin-gonic是go语言开发的轻量级web框架&#xff0c;性能优异&#xff0c;代码简洁&#xff0c;功能强大。有很多值得学习的地方,最近准备把这段时间学习gin的知识点&#xff0c;通过engine&#xff0c;context&#xff0c;router…

git操作:修改本地的地址

Windows下git如何修改本地默认下载仓库地址 - 简书 (jianshu.com) 详细解释&#xff1a; 打开终端拉取git时&#xff0c;会默认在git安装的地方&#xff0c;也就是终端前面的地址。 需要将代码 拉取到D盘的话&#xff0c;现在D盘创建好需要安放代码的文件夹&#xff0c;然后…

监控无人机项目

监控无人机的开发涉及多个方面&#xff0c;涵盖硬件、软件和网络等领域。下面是一般情况下开发监控无人机系统的主要步骤&#xff1a; 确定需求和功能&#xff1a;明确您的监控无人机系统的目标和应用场景&#xff0c;确定需要的功能和特性&#xff0c;例如实时视频监控、目标…

Linux中软件RAID的使用

在Linux系统中目前以MD (Multiple Devices)虚拟块设备的方式实现软件RAID&#xff0c;利用多个底层的块设备虚拟出一个新的虚拟块设备&#xff0c;并且利用条带化(stripping)技术将数据块均匀分布到多个磁盘上来提高虚拟设备的读写性能&#xff0c;利用不同的数据冗余算法来保护…

聚焦甲烷循环,宏基因组分析项目再创新!

甲烷&#xff0c;化学式CH4&#xff0c;在自然界分布很广&#xff0c;是最简单的有机物&#xff0c;也是最简单的烃。但同时也是一种重要的温室气体&#xff0c;是一种仅次于二氧化碳的强大温室气体&#xff0c;对环境和全球变化具有重大影响&#xff0c;其导致全球变暖潜力是C…

C++ has a different exception specifier

这个报错&#xff1a; error: declaration of ‘virtual const void* int8EntroyCalibrator::readCalibrationCache (std::size_t&)’ has a different exception specifier正常来说就是你声明的函数定义和真正函数实现的时候&#xff0c;参数或者函数类型不一致&#xff…

uniapp使用getStorage对属性赋值无效

1正常set(get)storage都是可以正常使用的 2.但对属性进行赋值的时候&#xff0c;却发现this.name并没有发生变化 3. 在里面打印this发现&#xff0c;在set*getStorage中并不能拿到this. 4.优化代码 这样就可以给this.name成功赋值

Python 装饰器该如何理解?

哈喽大家好&#xff0c;今天带大家了解下在Python中装饰器的使用 定义 首先我们先来了解下装饰器的定义。顾名思义&#xff0c;在Python中&#xff0c;装饰器本质上就是一个函数&#xff0c;它可以接收一个函数作为参数&#xff0c;然后返回一个新的函数。这个新的函数可以在…

Redis(主从复制、哨兵模式、集群)概述及部署

文章目录 一、Redis模式二、Redis 持久化1.Redis 提供两种方式进行持久化&#xff1a;2.RDB 持久化2.1 触发条件2.2 执行流程2.3 启动时加载 3.AOF持久化3.1 执行流程3.1.1 命令追加(append)3.1.2 文件写入(write)和文件同步(sync)3.1.3 文件重写(rewrite) 3.2 文件重写的触发&…

flutter开发实战-显示本地图片网络图片及缓存目录图片

flutter开发实战-显示本地图片网络图片及缓存目录图片 在最近开发中碰到了需要显示缓存目录图片&#xff0c;这里顺便整理一下&#xff0c;显示本地图片、网络图片、缓存目录图片的方法。 一、工程本地图片显示 1 在项目根目录下创建名为 images文件夹&#xff0c;也可以将i…

JavaFX知识了解

这篇文章的内容是和某PT问答对话而来的&#xff0c;不得不说很快很方便的了解了JavaFX的知识&#xff0c;真的是很强大。 虽然Java Swing也能做UI&#xff0c;并且跨平台&#xff0c;但是JavaFX提供了更优秀的一个选项&#xff0c;值得业余探索和了解学习。桌面软件开发现在选项…

uni-app点击按钮弹出提示框(以弹窗的形式显示),选择确定和取消

学习目标&#xff1a; 学习目标如下所示&#xff1a; uni-app点击提交按钮后弹出提示框&#xff0c;&#xff08;以弹窗的形式显示&#xff09;,提示用户是否确认提交&#xff08;即确定和取消&#xff09;&#xff0c;点击确定后调用真正的提交方法&#xff0c;将数据传给后端…

【计算机视觉|人脸建模】3D人脸重建基础知识(入门)

本系列博文为深度学习/计算机视觉论文笔记&#xff0c;转载请注明出处 一、三维重建基础 三维重建&#xff08;3D Reconstruction&#xff09;是指根据单视图或者多视图的图像重建三维信息的过程。 1. 常见三维重建技术 人工几何模型仪器采集基于图像的建模描述基于几何建模…

linux常用库记录(mqtt/json等库)

libcurl库: libcurl 是一个跨平台网络协议库,http,https,telnet,ftp等协议都支持\ jrtplib库:实时传输协议&#xff08;Real-time Transport Protocol&#xff0c;PRT&#xff09;是在 Internet 上处理多媒体数据流的一种网络协议&#xff0c;利用它能够在一对一&#xff08;un…

20230726----重返学习-vue3项目实战-知乎日报第3天-TS-简历

day-121-one-hundred-and-twenty-one-20230726-vue3项目实战-知乎日报第3天-TS-简历 vue3项目实战-知乎日报第3天 封装按钮组件 jsx函数式组件 只能做静态页面&#xff0c;内部没有方法让它自动更新。 封装第三方按钮-非计算属性版 封装第三方按钮-不使用计算属性 src/c…

netty 错误

项目场景&#xff1a; 提示&#xff1a;这里简述项目相关背景&#xff1a; 问题描述 提示&#xff1a;这里描述项目中遇到的问题&#xff1a; 七月 28, 2023 11:12:49 上午 org.jboss.netty.channel.SimpleChannelHandler 警告: EXCEPTION, please implement cn.com.onlinet…