Qt —UDP通信QUdpSocket 简介 +案例

1. UDP通信概述


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

   QUdpSocket以数据报传输数据,而不是以连续的数据流。发送数据报使用函数         QUdpSocket::writeDatagram()数据报的长度一般少于512字节,每个数据报包含发送者和接收者的IP地址和端口等信息。
     UDP数据接收,首先要使用QUdpSocket::bind()绑定一个端口,绑定端口后,socket的状态会变为已绑定状态“BoundState”。

当有数据报传入时,QudpSocket会自动发射readyRead()信号,在其槽函数中使用QUdpSocket::readDatagram()进行数据读取。abort()为解除绑定,解除后socket状态变为未连接状态“UnconnectedState”。

2. UDP消息传送的三种模式

单播模式(unicast):一个UDP客户端发送数据报到指定地址和端口的另一UDP客户端,是一对一的数据传输。

广播模式(broadcast):一个UDP客户端发出的数据报,在同一网络范围内其他所有的UDP客户端都可以收到。QUdpSocket支持IPv4广播。需要在数据报中指定接收端地址为QHostAddress::Broadcast,一般的广播地址是255.255.255.255

组播模式(multicast):UDP客户端加入到另一个组播IP地址的多播组,成员向组播地址发送的数据报,其加入组播的所有成员都可以接收到,类似于QQ群功能。QUdpSocket::joinMulticastGroup()函数实现加入多播组的功能。

QUdpSocket::leaveMulticastGroup()函数实现

在单播、广播和多播模式下,UDP程序都是对等的,不像TCP通信分为客户端和服务端。
TCP通信只有单播模式。UDP通信虽然不能保证数据传输的准确性,但是具有灵活性,一般的即时通信软件都是基于UDP通信的。

3. QUdpSocket类的接口函数

bool bind(quint16 port = 0)  为UDP通信绑定一个端口

qint64 writeDatagram(QByteArray& datagram, QHostAddress& host, quint16 port) 向目标地址和端口的UDP客户端发送数据报,返回成功发送的字节数,数据报的长度一般不超过512字节。

bool hasPendingDatagrams()     当至少有一个数据报需要读取时,返回true

qint64 pendingDatagramSize()    返回第一个待读取的数据报的大小

qint64 readDatagram(char* data, qint64 maxSize) 读取一个数据报,返回成功读取的字节数

qint64 readDatagram(char* data, qint64 maxSize, QHostAddress* address, quint16* port) 读取一个数据报,返回成功读取的字节数。发送方的主机地址和端口存储在*address和*port中(除非指针为0)

bool joinMulticastGroup(QHostAddress& groupAddress)      加入一个多播组

bool leaveMulticastGroup(QHostAddress& groupAddress)    离开一个多播组

void abort() 终止当前连接并重置套接字。通常在析构函数中写入。与disconnectFromHost()不同,该函数立即关闭套接字,丢弃写入缓冲区中的任何挂起数据。
原文链接:https://blog.csdn.net/WL0616/article/details/129050373

4.UDP对话小案例

实现发送和接收端互相发信息,类似QQ  (界面使用UI设计)

4.1.接收端

receiver.h

#ifndef RECESIVER_H
#define RECESIVER_H

#include <QWidget>
#include <QUdpSocket>
QT_BEGIN_NAMESPACE
namespace Ui { class Recesiver; }
QT_END_NAMESPACE

class Recesiver : public QWidget
{
    Q_OBJECT

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

private slots:
    void on_pushButton_2_clicked(); //启动槽函数
    void start();
    void on_pushButton_clicked();

private:
    Ui::Recesiver *ui;
    QUdpSocket *receiver;
};
#endif // RECESIVER_H

receiver.cpp

#include "recesiver.h"
#include "ui_recesiver.h"

Recesiver::Recesiver(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Recesiver)
{
    ui->setupUi(this);
    setWindowTitle(QStringLiteral("接收端"));
    ui->lineEdit->setText("127.0.0.1");
    receiver =new QUdpSocket(this);
}

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

//接收信息
 void Recesiver::start()
 {
    QByteArray datagram;
    datagram.resize(receiver->pendingDatagramSize()); //接收到的数据的长度
    receiver->readDatagram(datagram.data(),datagram.size());
    ui->textEdit->append(QStringLiteral("对方:")+datagram);
 }

//启动按钮(发送端发送信息给接收端)
void Recesiver::on_pushButton_2_clicked()
{
   receiver->bind(ui->lineEdit_2->text().toInt());//设置端口号将其转为整型
   connect(receiver,&QUdpSocket::readyRead,this,[&](){start();});
   ui->pushButton_2->setEnabled(false);
   ui->lineEdit_2->setEnabled(false);
}

//发送按钮(接收端发送信息给发送端)
void Recesiver::on_pushButton_clicked()
{
    QByteArray datagram=ui->textEdit_2->toPlainText().toUtf8();  //在输入端输入发送的内容
    receiver->writeDatagram(datagram.data(),datagram.size(),QHostAddress(ui->lineEdit->text()),ui->lineEdit_3->text().toInt());
    //qint64 writeDatagram(const char *data, qint64 len, const QHostAddress &host, quint16 port);
    //发送数据,大小,发送主机的ip,发送主机的端口号
    ui->textEdit->append(QStringLiteral("本机:")+ui->textEdit_2->toPlainText());//发送信息的具体内容在发送端的聊天记录里能体现
    ui->textEdit_2->clear();
}

4.2发送端

sender.h

#ifndef SENDER_H
#define SENDER_H
#include <QWidget>
#include <QUdpSocket>
QT_BEGIN_NAMESPACE
namespace Ui { class Sender; }
QT_END_NAMESPACE

class Sender : public QWidget
{
    Q_OBJECT

public:
    Sender(QWidget *parent = nullptr);
    ~Sender();
    void  start2();
private slots:
    void on_pushButton_clicked();

private:
    Ui::Sender *ui;
    QUdpSocket *sender;
};
#endif // SENDER_H

sender.cpp

#include "sender.h"
#include "ui_sender.h"

Sender::Sender(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Sender)
{
    ui->setupUi(this);
    sender=new QUdpSocket(this);
    setWindowTitle(QStringLiteral("发送端"));

    //sender
    ui->lineEdit_3->setText("888");
    sender->bind(ui->lineEdit_3->text().toInt());//绑定端口号

    connect(sender,&QUdpSocket::readyRead,this,[&](){start2();});
    //start2();
}

void Sender::start2()
{
    QByteArray datagram;
    datagram.resize(sender->pendingDatagramSize()); //接收到的数据的长度
    sender->readDatagram(datagram.data(),datagram.size());
    ui->textEdit->append(QStringLiteral("对方:")+datagram);
}


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


//发送按钮 发送信息给接收端
void Sender::on_pushButton_clicked()
{
   QByteArray datagram=ui->textEdit_2->toPlainText().toUtf8();  //在输入端输入发送的内容
   sender->writeDatagram(datagram.data(),datagram.size(),QHostAddress(ui->lineEdit->text()),ui->lineEdit_2->text().toInt());
   //qint64 writeDatagram(const char *data, qint64 len, const QHostAddress &host, quint16 port);
   //发送数据,大小,发送主机的ip,发送主机的端口号
   ui->textEdit->append(QStringLiteral("
  • 4
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Qt是一个跨平台的C++应用程序开发框架,它提供了丰富的类库和工具,可以用于开发各种类型的应用程序,包括图形界面应用程序、网络应用程序等。UDP是一种无连接的传输协议,它可以实现快速的数据传输,适用于对数据传输速度要求较高的场景。在Qt中,可以使用QUdpSocket类来实现UDP通信。 QUdpSocket类是Qt提供的用于UDP通信的类,它继承自QAbstractSocket类。使用QUdpSocket类可以实现UDP的发送和接收功能。下面是一个简单的示例代码,演示了如何使用Qt进行UDP通信: ```cpp // 创建QUdpSocket对象 QUdpSocket udpSocket; // 绑定本地端口 udpSocket.bind(QHostAddress::Any, 1234); // 发送数据 QByteArray data = "Hello, UDP!"; udpSocket.writeDatagram(data, QHostAddress::LocalHost,5678); // 接收数据 connect(&udpSocket, &QUdpSocket::readyRead, [&]() { while (udpSocket.hasPendingDatagrams()) { QByteArray datagram; datagram.resize(udpSocket.pendingDatagramSize()); udpSocket.readDatagram(datagram.data(), datagram.size()); qDebug() << "Received data:" << datagram; } });``` 上述代码首先创建了一个QUdpSocket对象udpSocket,并绑定了本地端口1234。然后使用writeDatagram函数发送数据,将数据发送到本地主机的5678端口。接着使用readyRead信号和readDatagram函数来接收数据,当有数据到达时,会触发readyRead信号,然后通过readDatagram函数读取数据。 通过上述示例代码,你可以了解到如何使用Qt进行UDP通信。如果你有更具体的问题或者需要更详细的介绍,请告诉我。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值