【QT学习笔记】QT教程:udp网络编程示例

文章详细描述了使用Qt库在C++中实现的UDP客户端和服务器端通信,涉及单播、广播和组播功能,包括初始化套接字、发送和接收数据的函数实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

分为客户端和服务器端代码示例

客户端

.h文件

#ifndef UDPCLIENT_H
#define UDPCLIENT_H

#include <QMainWindow>
#include <QUdpSocket>
#include <QObject>
#include <QHostAddress>
#include <QDebug>
#include <QTimer>

QT_BEGIN_NAMESPACE
namespace Ui { class UDPClient; }
QT_END_NAMESPACE

class UDPClient : public QMainWindow
{
    Q_OBJECT

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

    void InitSocket();//初始化UDP套接字

    void InitTimer();//初始化定时器

private:
    Ui::UDPClient *ui;

    QUdpSocket *UdpClient;

    QUdpSocket *mUdpSocket;//UDP套接字对象
    QHostAddress mGroupAddress;//组播地址
    QTimer *mTimer;//定时器对象
    int mType;//记录UDP消息传送模式 0:单播 1:广播 2:组播(多播)

private slots:
    void send();
    void SendData();//发送数据

};
#endif // UDPCLIENT_H

 .cpp文件

#include "udpclient.h"
#include "ui_udpclient.h"

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

    //客户端实现发送数据
    //    mType = 0;//Unicast   单播
    //    mType = 1;//Broadcast 广播
    mType = 2;//Multicast   组播
    InitSocket();

//    UdpClient = new QUdpSocket(this);
    connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(send()));
}

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

void UDPClient::send()
{
    InitTimer();
//    UdpClient->writeDatagram(ui->lineEdit->text().toUtf8(),QHostAddress("192.168.8.113"),6666);

}

void UDPClient::InitSocket()
{
    mUdpSocket = new QUdpSocket;//初始化socket
    mGroupAddress.setAddress("239.2.2.222");//设置组播地址
    mUdpSocket->bind(6666);//绑定端口号
    if(mType == 2)  //组播
    {
        //组播的数据的生存期,数据报每跨1个路由就会减1.表示多播数据报只能在同一路由下的局域网内传播
        mUdpSocket->setSocketOption(QAbstractSocket::MulticastTtlOption,1);
    }
}

void UDPClient::InitTimer()
{
    mTimer = new QTimer;//初始化定时器
    connect(mTimer,&QTimer::timeout,this,[=]
            {
                SendData();
            });
    mTimer->start(1000);//每隔一秒发送一次数据
}

void UDPClient::SendData()
{
    QByteArray _data = "hello";
    if(mType == 0)//单播
    {
        QHostAddress _peerHostAddress = QHostAddress("10.0.0.177");//对位服务器IP
        quint16 _port = 6666;//对位服务器端口

        if(-1 !=mUdpSocket->writeDatagram(_data.data(),_data.size(),_peerHostAddress,_port))
        {//调用用来向指定IP地址和端口发送数据。_data.data()指向待发送数据的起始位置,_data.size()则是要发送的数据长度
            //如果writeDatagram()函数返回值不等于-1,说明数据成功发送出去
            qDebug()<< "Unicast ==> Send data : "<< _data<<endl;
        }

        mUdpSocket->flush();
        //确保所有缓冲区中的数据都被立即发送到网络上。
        //对于UDP套接字来说,flush()通常是冗余的,
        //因为UDP是无连接的,并且写入操作通常都是立即执行的(但某些情况下,比如非阻塞模式下,可能有内部缓冲)
    }
    else if(mType == 1)//广播
    {
        quint16 _port = 6666;//广播端口
        if(-1 !=mUdpSocket->writeDatagram(_data.data(),QHostAddress::Broadcast,_port))
        {
            qDebug()<< "Broadcast ==> Send data : "<< _data<<endl;
        }
        mUdpSocket->flush();
    }
    else if(mType == 2)//组播
    {
        quint16 _port = 8888;//组播端口
        if(-1 != mUdpSocket->writeDatagram(_data.data(),mGroupAddress,_port))
        {
            qDebug()<< "Multicast ==> Send data : "<< _data<<endl;
        }
        mUdpSocket->flush();
    }
    else
    {
        qDebug()<< "mType is error! "<<endl;
        return;
    }

}

服务器端

.h文件

#ifndef UDPSERVER_H
#define UDPSERVER_H

#include <QMainWindow>
#include <QObject>
#include <QHostAddress>
#include <QUdpSocket>
#include <QDebug>

QT_BEGIN_NAMESPACE
namespace Ui { class UDPServer; }
QT_END_NAMESPACE

class UDPServer : public QMainWindow
{
    Q_OBJECT

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

    void readyData();
    void InitSocket();//初始化套接字

public slots:
    void ReadPendingDataframs();//读取消息

private:
    Ui::UDPServer *ui;

    QUdpSocket *UdpServer;

    QUdpSocket *mUdpSocket;//UDP套接字
    QHostAddress mGroupAdress;//组播地址
    int mType; //记录UDP消息传送模式 0:单播 1:广播  2:组播(多播)
};
#endif // UDPSERVER_H

.cpp文件

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

UDPServer::UDPServer(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::UDPServer)
{//服务器端实现数据的接收
    //    mType = 0;//Unicast  单播
    //    mType = 1;//Broadcast 广播
    mType = 2;//Multicast   组播
    InitSocket();

    ui->setupUi(this);

//    UdpServer = new QUdpSocket(this);
//    UdpServer->bind(QHostAddress::Any, 6666);
//    connect(UdpServer, SIGNAL(readyRead()), this, SLOT(readData()));
}

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

void UDPServer::readyData()
{
//    QByteArray arr;
//    arr.resize(UdpServer->bytesAvailable());
//    UdpServer->readDatagram(arr.data(),arr.size());
//    ui->lineEdit->setText(arr);
}

void UDPServer::InitSocket()
{
    //初始化socket,设置组播地址
    mUdpSocket = new QUdpSocket;
    mGroupAdress.setAddress("239.2.2.222");
    if(mType == 0 || mType == 1)
    {
        //绑定本地IP和端口号
        mUdpSocket->bind(6666);
    }
    else if(mType == 2)
    {
        if(mUdpSocket->bind(QHostAddress::AnyIPv4,8888,QUdpSocket::ShareAddress))
        {
            //加入组播地址
            mUdpSocket->joinMulticastGroup(mGroupAdress);
            qDebug()<<("Join Multicast Adrress [")<<mGroupAdress.toString()
                     <<("] Successful!")<<endl;
        }
    }
    else
    {
        qDebug()<< "mType is error! "<<endl;
        return;
    }

    connect(mUdpSocket,&QUdpSocket::readyRead,this,[=]{
        ReadPendingDataframs();
    });
}

void UDPServer::ReadPendingDataframs()
{
    QByteArray _data;
    _data.resize(mUdpSocket->pendingDatagramSize());
    if(mType == 0)//Unicast
    {
        QHostAddress *_peerHostAddress = new QHostAddress("10.0.0.32");
        quint16 _port = 6666;
        while(mUdpSocket->hasPendingDatagrams())
        {
            mUdpSocket->readDatagram(_data.data(),_data.size(),_peerHostAddress,&_port);//接收指定IP和端口的udp报文
            qDebug()<<"Unicast ==> Receive data : "<<QString::fromLatin1(_data)<<endl;
            ui->lineEdit->setText(_data);
            ui->textEdit->append(_data);
        }
    }
    else if(mType == 1)//Broadcast
    {
        QHostAddress _peerHostAddress;
        quint16 _port;
        while(mUdpSocket->hasPendingDatagrams())
        {
            mUdpSocket->readDatagram(_data.data(),_data.size(),&_peerHostAddress,&_port);//接收同一子网的udp报文
            qDebug()<<"Broadcast ==> Receive data : "<<QString::fromLatin1(_data)<<endl;
            ui->lineEdit->setText(_data);
            ui->textEdit->append(_data);
        }
    }
    else if(mType == 2)//Multicast
    {
        QHostAddress _peerHostAddress;
        quint16 _port;
        while(mUdpSocket->hasPendingDatagrams())
        {
            mUdpSocket->readDatagram(_data.data(),_data.size(),&_peerHostAddress,&_port);//接收同组的udp报文
            qDebug()<<"Multicast ==> Receive data : "<<QString::fromLatin1(_data)<<endl;
            ui->lineEdit->setText(_data);
            ui->textEdit->append(_data);
        }
    }
    else
    {
        qDebug()<< "mType is error! "<<endl;
        return;
    }
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奇异果冻

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值