欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Qt通信之Udp(客户端和服务端)20.11.27

程序员文章站 2022-07-01 15:15:15
...

Qt通信之Udp(客户端和服务端)20.11.27
可以看出,在UDP方式下客户端并不与服务器建立连接,它只负责调用发送函数向服务器发送数据报。相同,服务器也不从客户端接收连接,只负责调用接收函数,等待来自某客户端的数据到达。
Qt中通过QUdpSocket类实现UDP协议的编程。接下来通过一个实例,介绍如何实现基于UDP协议的广播应用,它由UDP服务器和UDP客户端两部分组成。

首先是客户端(Client)
Qt通信之Udp(客户端和服务端)20.11.27
这个是接收到服务端返回的消息–渲染。
服务端(Server)
Qt通信之Udp(客户端和服务端)20.11.27
Edit是我发送给客户端的内容。

这个demo的目的–
我在服务端输入任意内容,并点击开始。他会把内容发给客户端。(我在服务端加了定时器,所以他会每秒发一次,所以客户端也会每秒接收一次内容)。
Qt通信之Udp(客户端和服务端)20.11.27
UdpClient.h

#ifndef UDPCLIENT_H
#define UDPCLIENT_H

#include <QDialog>
#include <QVBoxLayout>
#include <QTextEdit>
#include <QPushButton>
#include <QUdpSocket>

class UdpClient : public QDialog
{
    Q_OBJECT

public:
    UdpClient(QWidget *parent = 0, Qt::WindowFlags f=0);
    ~UdpClient();

public slots:
    void CloseBtnClicked();
    void dataReceived();

private:
    QTextEdit *ReceiveTextEdit;
    QPushButton *CloseBtn;
    QVBoxLayout *mainLayout;

    int port;
    QUdpSocket *udpSocket;

};

#endif // UDPCLIENT_H

UdpClient.cpp

#include "udpclient.h"

#include <QMessageBox>
#include <QHostAddress>
UdpClient::UdpClient(QWidget *parent, Qt::WindowFlags f)
    : QDialog(parent, f)
{
    setWindowTitle(tr("UDP Client"));

    ReceiveTextEdit = new QTextEdit(this);
    CloseBtn = new QPushButton(tr("Close"), this);

    mainLayout = new QVBoxLayout(this);
    mainLayout->addWidget(ReceiveTextEdit);
    mainLayout->addWidget(CloseBtn);

    connect(CloseBtn, SIGNAL(clicked()), this, SLOT(CloseBtnClicked()));

    port = 555;

    udpSocket = new QUdpSocket(this);
    connect(udpSocket, SIGNAL(readyRead()), this, SLOT(dataReceived()));

    bool result = udpSocket->bind(port);
    if(!result)
    {
        QMessageBox::information(this, tr("error"), tr("udp socket create error!"));
        return;
    }
}

UdpClient::~UdpClient()
{

}

void UdpClient::CloseBtnClicked()
{
    close();
}

void UdpClient::dataReceived()
{
    while(udpSocket->hasPendingDatagrams())
    {
        QByteArray datagram;
        datagram.resize(udpSocket->pendingDatagramSize());

        udpSocket->readDatagram(datagram.data(),datagram.size());
        QString msg = datagram.data();
        ReceiveTextEdit->insertPlainText(msg);
    }
}

UdpServer.h

#ifndef UDPSERVER_H
#define UDPSERVER_H

#include <QDialog>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QVBoxLayout>
#include <QUdpSocket>
#include <QTimer>
class UdpServer : public QDialog
{
    Q_OBJECT

public:
    UdpServer(QWidget *parent = 0);
    ~UdpServer();
public slots:
    void StartBtnClicked();
    void timeout();
private:
    QLabel *TimerLabel;
    QLineEdit *TextLineEdit;
    QPushButton *StartBtn;
    QVBoxLayout *mainLayout;

    int port;
    bool isStarted;
    QUdpSocket *udpSocket;
    QTimer *timer;
};

#endif // UDPSERVER_H

UdpServer.cpp

#include "udpserver.h"
#include <QHostAddress>
UdpServer::UdpServer(QWidget *parent)
    : QDialog(parent)
{
    setWindowTitle(tr("UDP Server"));

    TimerLabel = new QLabel(tr("计算器:"), this);
    TextLineEdit = new QLineEdit(this);
    StartBtn = new QPushButton(tr("开始"), this);

    mainLayout = new QVBoxLayout(this);
    mainLayout->addWidget(TimerLabel);
    mainLayout->addWidget(TextLineEdit);
    mainLayout->addWidget(StartBtn);

    connect(StartBtn, SIGNAL(clicked()), this, SLOT(StartBtnClicked()));
    port = 555;
    isStarted=false;
    udpSocket = new QUdpSocket(this);
    timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(timeout()));
}

UdpServer::~UdpServer()
{

}

void UdpServer::StartBtnClicked()
{
    if(!isStarted)
    {
        StartBtn->setText(tr("停止"));
        timer->start(1000);
        isStarted = true;
    }
    else
    {
        StartBtn->setText(tr("开始"));
        isStarted = false;
        timer->stop();
    }
}

void UdpServer::timeout()
{
    QString msg = TextLineEdit->text();
    int length = 0;
    if(msg=="")
    {
        return;
    }
    if((length=udpSocket->writeDatagram(msg.toLatin1(),
    msg.length(), QHostAddress::Broadcast,port)) != msg.length())
    {
        return;
    }
}

同时运行UdpServer和UdpClient工程。记住,要分为两个工程实现!
需要完整源码请移步我的CSDN资源。