Qt之UDP通信

这篇具有很好参考价值的文章主要介绍了Qt之UDP通信。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一、UDP简介

二、QUdpSocket类

三、UDP服务器

四、UDP客户端

五、代码

1.udp服务端

2.udp客户端


一、UDP简介

UDP(User Datagram Protocol 即用户数据报协议)是一个轻量级的,不可靠的,面向数据
报的无连接协议
。由于 UDP 的特性:它不属于连接型协议,因而具有资源消耗小,处理速度快的优点,所以通常音频、视频和普通数据在传送时使用 UDP 较多,因为它们即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。

UDP 通信示意图如下:

qt udp,QT,udp,网络协议,网络

UDP 消息传送有三种模式,分别是单播广播组播三种模式。

①单播(unicast): 单播用于两个主机之间的端对端通信,需要知道对方的 IP 地址与端口

②广播(broadcast): 广播 UDP 与单播 UDP 的区别就是 IP 地址不同,广播一般使用广播地址
255.255.255.255,将消息发送到在同一广播(也就是局域网内同一网段) 网络上的每个主机

注意:本地广播信息是不会被路由器转发所以如果一个服务端在win,另外一个客户端在虚拟机说,这时就需要配置虚拟机的端口转发,这样虚拟机才会连得上服务器

qt udp,QT,udp,网络协议,网络

③组播(multicast): 组播(多点广播),也称为多播,将网络中同一业务类型主机进行了逻辑上的分组,进行数据收发的时候其数据仅仅在同一分组中进行,其他的主机没有加入此分组不能收发对应的数据。

在广域网上广播的时候,其中的交换机和路由器只向需要获取数据的主机复制并转发数据。主机可以向路由器请求加入或退出某个组,网络中的路由器和交换机有选择地复制并传输数据,将数据仅仅传输给组内的主机。多播的这种功能,可以一次将数据发送到多个主机,又能保证不影响其他不需要(未加入组)的主机的其他通信。

注意: 单播一样和多播是允许在广域网即 Internet 上进行传输的,而广播仅仅在同一局域网上才能进行

二、QUdpSocket类

QT 的 socket 类之间的关系: 

qt udp,QT,udp,网络协议,网络

QUdpSocket 类提供了一个 UDP 套接字。 QUdpSocket 是 QAbstractSocket 的子类,允许发
送和接收 UDP 数据报。

常用API函数

①构造函数

QUdpSocket::QUdpSocket(QObject *parent = Q_NULLPTR)

②如果至少有一个数据报在等待被读取,则返回true,否则返回false。

bool QUdpSocket::hasPendingDatagrams() const 

③服务器绑定端口

bool bind(const QHostAddress &address, quint16 port = 0, BindMode mode = DefaultForPlatform);

④返回第一个待处理的UDP数据报的大小Byte。如果没有可用的数据报,该函数返回-1。

qint64 QUdpSocket::pendingDatagramSize() const

⑤接收数据

qint64 QUdpSocket::readDatagram(char *data, qint64 maxSize, QHostAddress *address = Q_NULLPTR, quint16 *port = Q_NULLPTR)

接收一个不大于maxSize字节的数据报并将其存储在data中。发送者的主机地址和端口存储在*address和*port中(除非指针为0)。成功时返回数据报的大小;否则返回-1。

如果maxSize太小,数据报的其余部分将被丢失。为了避免数据丢失,在试图读取数据报之前,应调用pendingDatagramSize()来确定未决数据报的大小。如果maxSize为0,数据报将被丢弃。
 

⑥发送数据

qint64 QUdpSocket::writeDatagram(const char *data, qint64 size, const QHostAddress &address, quint16 port)

将数据报以大小的方式发送到端口端口的主机地址。成功时返回发送的字节数,否则返回-1。
数据报总是被写成一个块。数据报的最大尺寸与平台高度相关,但可以低至8192字节。如果数据报太大,这个函数将返回-1,error()将返回DatagramTooLargeError。

一般来说,发送大于512字节的数据报是不利的,因为即使它们被成功发送,在到达最终目的地之前,它们很可能被IP层分割开来。

 三、UDP服务器

 1.创建QUdpSocket对象

mSocket = new QUdpSocket(this);

②绑定地址和端口号

msocket->bind(ip,端口号);

③收到数据时,会触发readyRead()信号,自定义readPendingDatagrams()进行读取数据;

connect(msocket,&QUdpSocket::readyRead, this,&Widget::readPendingDatagrams);

④在while循环中读取数据,只要有数据,就一直读取并处理。

  void Server::readPendingDatagrams()
  {
      while (udpSocket->hasPendingDatagrams()) //数据报等待被读取

       {
                 //数据缓冲区

                QByteArray arr;

                //调整缓冲区的大小和收到的数据大小一致                 

                arr.resize(mSocket->bytesAvailable()); //接收数据

                mSocket->readDatagram(arr.data(),arr.size(),&addr,&port);

                //将arr.data转为字符串即可

                QString str = arr.data();

      }
  }

通信(先接收) 收到数据会触发信号readyRead, 通过QUdpSocket对象的readDatagram函数来接收数据 。

readyRead()信号在数据报到达时发出。在这种情况下, hasPendingDatagrams()返回 true。调用 pendingDatagramSize()来获取第一个待处理数据报的大小,并调用 readDatagram()接收数据。

注意:当接收到readyRead()信号时,一个传入的数据报应该被读取,否则这个信号将不会被发送到下一个数据报。

⑤发送数据

qint64 QUdpSocket::writeDatagram(const char *data, qint64 size, const QHostAddress &address, quint16 port)

若是广播消息,与单播消息不同的是将目标 IP 地址换成了广播地址,一般广播地址为 255.255.255.255,也可以使用QHostAddress::Broadcast获取广播地址

QHostAddress peerAddr = QHostAddress::Broadcast;

只需要将客户端发送数据:writeDatagramIP地址改为广播地址即可

四、UDP客户端

①创建QUdpSocket对象

mSocket = new QUdpSocket(this);

②发送数据到指定的地址和端口号

writeDatagram(数据,接收方ip,接收方端口号);

 发送的数据要是QByteArray类型,Qt中将字符串转为QByteArray可以使用.toUtf8函数

五、代码

1.udp服务端

 头文件

#ifndef UDPSERVER_H
#define UDPSERVER_H

#include <QWidget>
#include <QtNetwork>

QT_BEGIN_NAMESPACE
namespace Ui { class UdpServer; }
QT_END_NAMESPACE

class UdpServer : public QWidget
{
    Q_OBJECT

public:
    UdpServer(QWidget *parent = nullptr);
    ~UdpServer();

private slots:
    void on_pushButton_start_clicked();

    void on_pushButton_send_clicked();
    void readPendingDatagrams();

private:
    Ui::UdpServer *ui;
    //Udp服务器
    QUdpSocket *mSocket;
    //通信的ip和端口,用于获取发送者的 IP 和端口
    QHostAddress addr;
    quint16 port;
};
#endif // UDPSERVER_H

源文件

#include "udpserver.h"
#include "ui_udpserver.h"

UdpServer::UdpServer(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::UdpServer)
{
    ui->setupUi(this);
}

UdpServer::~UdpServer()
{
    delete ui;
}

//启动
void UdpServer::on_pushButton_start_clicked()
{
    //1.创建QUdpSocket对象
    mSocket = new QUdpSocket(this);

    //2.连接接收数据信号和槽
    QObject::connect(mSocket,&QUdpSocket::readyRead,this,&UdpServer::readPendingDatagrams);


    //3.绑定
    mSocket->bind(QHostAddress::Any,ui->spinBox->value());

    //连接回车发送的信号和槽
    QObject::connect(ui->lineEdit,&QLineEdit::returnPressed,this,&UdpServer::on_pushButton_send_clicked);

    //禁止端口号和启动按钮
    ui->spinBox->setEnabled(false);
    ui->pushButton_start->setEnabled(false);
}

void UdpServer::on_pushButton_send_clicked()
{
    //获取发送的数据
    QByteArray arr = ui->lineEdit->text().toUtf8();

    //发送
    mSocket->writeDatagram(arr,addr,port);
    //显示发送的内容
    ui->textBrowser->insertPlainText("send:"+QString(arr)+"\n");
    //情况lineEdit
    ui->lineEdit->clear();
}

void UdpServer::readPendingDatagrams()
{
    //数据缓冲区
    QByteArray arr;
    while(mSocket->hasPendingDatagrams())
    {

        //调整缓冲区的大小和收到的数据大小一致
        arr.resize(mSocket->bytesAvailable());

        //接收数据
        mSocket->readDatagram(arr.data(),arr.size(),&addr,&port);
        //显示
        ui->textBrowser->insertPlainText(addr.toString()+":"+QString(arr)+"\n");

        //使能发送按钮和编辑框
        ui->lineEdit->setEnabled(true);
        ui->pushButton_send->setEnabled(true);
    }
}

2.udp客户端

头文件

#ifndef UDPCILENT_H
#define UDPCILENT_H

#include <QWidget>
#include <QtNetwork>

QT_BEGIN_NAMESPACE
namespace Ui { class UdpCilent; }
QT_END_NAMESPACE

class UdpCilent : public QWidget
{
    Q_OBJECT

public:
    UdpCilent(QWidget *parent = nullptr);
    ~UdpCilent();

private slots:
    void on_pushButton_send_clicked();
    void readPendingDatagrams();

private:
    Ui::UdpCilent *ui;
    //UDP客户端
    QUdpSocket *mSocket;
};
#endif // UDPCILENT_H

 源文件

#include "udpcilent.h"
#include "ui_udpcilent.h"

UdpCilent::UdpCilent(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::UdpCilent)
{
    ui->setupUi(this);
    //1.创建QUdpSocket
    mSocket = new QUdpSocket(this);
    //2.通信(接收)
    QObject::connect(mSocket,&QUdpSocket::readyRead,this,&UdpCilent::readPendingDatagrams);

    //连接回车发送的信号和槽
    QObject::connect(ui->lineEdit_send,&QLineEdit::returnPressed,this,&UdpCilent::on_pushButton_send_clicked);

}

UdpCilent::~UdpCilent()
{
    delete ui;
}

//发送
void UdpCilent::on_pushButton_send_clicked()
{
    //获取发送的数据
    QByteArray arr = ui->lineEdit_send->text().toUtf8();

    //发送
    //mSocket->writeDatagram(arr,QHostAddress(ui->lineEdit_ip->text()),ui->spinBox->value());
    mSocket->writeDatagram(arr,QHostAddress::Broadcast,ui->spinBox->value());
    //显示发送的内容
    ui->textBrowser->insertPlainText("send:"+QString(arr)+"\n");
    //情况lineEdit
    ui->lineEdit_send->clear();
}

void UdpCilent::readPendingDatagrams()
{
    QHostAddress addr; //用于获取发送者的 IP 和端口
    quint16 port;
    //数据缓冲区
    QByteArray arr;
    while(mSocket->hasPendingDatagrams())
    {
        //调整缓冲区的大小和收到的数据大小一致
        arr.resize(mSocket->bytesAvailable());

        //接收数据
        mSocket->readDatagram(arr.data(),arr.size(),&addr,&port);
        //显示
        ui->textBrowser->insertPlainText(addr.toString()+":"+QString(arr)+"\n");
    }
}

结果: 
 qt udp,QT,udp,网络协议,网络

 文章来源地址https://www.toymoban.com/news/detail-786018.html

到了这里,关于Qt之UDP通信的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Qt通信TCP/UDP

    qt socket通信,QTcpServer,QTcpSocket,QUdpSocket 链接2 链接3 链接4 QT中不再用套接字进行通信,而是使用连接对

    2024年02月09日
    浏览(32)
  • Qt —UDP通信QUdpSocket 简介 +案例

       UDP是无连接、不可靠、面向数据报(datagram)的协议,可以应用于对可靠性要求不高的场合。与 TCP通信 不同,UDP通信无需预先建立持久的socket连接,UDP每次发送数据报都需要指定目标地址和端口。    QUdpSocket以数据报传输数据,而不是以连续的数据流。发送数据报使用函

    2024年02月10日
    浏览(23)
  • Qt 8. UDP客户端通信

    1. 代码 2. 效果 以上代码可以实现UDP收发功能。

    2024年02月13日
    浏览(31)
  • Qt - UDP网络编程

    UDP(User Datagram Protocol,用户数据报协议) UDP是一个轻量级、不可靠、面向数据报的、无连接的协议,多用于可靠性要求不严格,不是非常重要的传输。 QUdpSocket类继承自QAbstractSocket,用来发送和接收UDP数据报,”Socket”即套接字,套接字即IP地址+端口号。其中IP地址指定了网络

    2024年04月22日
    浏览(89)
  • 14-3_Qt 5.9 C++开发指南_QUdpSocket实现 UDP 通信_UDP 单播和广播

    UDP(User Datagram Protocol,用户数据报协议)是轻量的、不可靠的、面向 数据报 (datagram) 、无连接的协议,它可以用于对可靠性要求不高的场合。与 TCP 通信不同, 两个程序之间进行 UDP 通信无需预先建立持久的 socket 连接,UDP 每次发送数据报都需要指定目标地址和端口 (如图14-6

    2024年02月14日
    浏览(35)
  • Qt网络编程 (udp广播和接收例)

    使用两个项目 1 sender 用来广播\\\"hello world\\\"; 2 receiver 用来接收广播信息 1 创建Qdialog类 2 在sender.pro 中添加 QT +=network 一行代码 3 在sender.h 中声明类 class QUdpSocket; 在声明一个私有对象 QUdpSocket *sender; 4 在ui界面拖入一个按钮 用来触发广播信息 其槽函数如下 在sender.cpp 构造函数中添

    2024年02月11日
    浏览(29)
  • QT网络编程之实现UDP广播发送和接收

    一.UDP广播介绍 UDP广播地址固定IP地址为:XXX.XXX.XXX.255。 如果向全网段发送广播消息,那么广播地址为:255.255.255.255; 如果向单个网段发送广播消息,例如你的IP是192.168.31.104,那么广播地址为192.168.31.255。 广播消息接收方需要绑定0.0.0.0地址并监听指定端口即可收到广播的群

    2024年03月25日
    浏览(45)
  • [Qt网络编程]之UDP通讯的简单编程实现

    hello!欢迎大家来到我的Qt学习系列之 网络编程之UDP通讯的简单编程实现。 希望这篇文章能对你有所帮助!!! 本篇文章的相关知识请看我的上篇文章: 目录 UDP通讯  基于主窗口的实现  基于线程的实现          UDP数据报协议是一个面向无连接的传输层报文协议 ,它简

    2024年04月25日
    浏览(41)
  • QT网络编程TCP/UDP开发流程 制作网络调试助手

    1、QT的网络编程: TCP和UDP TCP编程需要用到俩个类: QTcpServer 和 QTcpSocket QTcpSocket类 提供了一个TCP套接字 QTcpSocket是QAbstractSocket的一个子类,它允许您建立TCP连接和传输数据流 注意:TCP套接字不能在QIODevice::Unbuffered模式下打开。 QTcpServer类 提供一个基于tcp的服务器 2. 这个类可以接

    2023年04月08日
    浏览(30)
  • 【Qt网络编程】实现TCP协议通信

    传输控制协议(TCP,Transmission Control Protocol)是 一种面向连接的、可靠的、基于字节流的传输层通信协议 ,由IETF的RFC 793 定义。 TCP建立连接前,需要进行三次握手,如下图所示: TCP断开连接前,需要进行四次挥手,如下图所示: Qt中提供了QTcpSocket类和QTcpServer类分别用于创

    2024年02月16日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包