Qt TCP/UDP network protocol introduction practice UDP communication

Keywords: Qt Network Protocol udp TCPIP

Source code:      NetToolsTest

For other QT Widge articles, please click here:      QT Widget learning notes

Sister articles:      Introduction and practice of Qt TCP/UDP network protocol (I) TCP communication

This article is just the simplest introductory study, which can be read further Flying clouds Big guy's source code QWidgetDemo , choose nettool, which is already a perfect network debugging assistant

UDP (User Datagram Protocol) is a lightweight, unreliable, datagram oriented connectionless protocol. Almost everyone now uses QQ, which uses UDP protocol to send messages when chatting. Just like QQ, when there are many users, most of them send short messages, which require timely response and low security requirements, UDP protocol is used. When choosing to use the protocol, you must be careful when choosing UDP. In the environment of unsatisfactory network quality, UDP packet loss will be more serious. However, due to the characteristics of UDP: it does not belong to the connection protocol, so it has the advantages of low resource consumption and fast processing speed. Therefore, UDP is usually used more for audio, video and ordinary data transmission, because even if they occasionally lose one or two packets, they will not have a great impact on the reception results. Therefore, QQ, a chat program that does not require high confidentiality, uses the UDP protocol.

The QUdpSocket class is provided in Qt to send and receive UDP datagrams. Here we also need to know a noun socket, which is often referred to as "socket". Socket simply means an IP address plus a port. Because if we want to transmit data, we need to know which machine to transmit to, and the IP address determines a host, but there may be various network programs running on this machine. Which program do we want to send to? At this time, a port is used to specify the UDP program. Therefore, socket indicates the path of datagram transmission.

This paragraph is taken from: Discussion on UDP UdpSocket communication example in Qt

1, UDP server

The demonstration of using UDP client communication in Qt is as follows:

● practical operation flow chart

● code

udpclinet.cpp

#include "udpclinet.h"
#include "ui_udpclinet.h"

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

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

//1. UI
//2. Initialization
//① Create QTcpSocket socket object
//② Establish a signal slot (readyRead) for socket to receive buffered data
void UdpClinet::initForm()
{
    socket = new QUdpSocket(this);
    connect(socket, SIGNAL(readyRead()), this, SLOT(readData()));
}

//3. Receive UDP data
void UdpClinet::readData()
{
    QHostAddress host;
    quint16 port;
    QByteArray data;

    while (socket->hasPendingDatagrams()) {
        data.resize(socket->pendingDatagramSize());
        socket->readDatagram(data.data(), data.size(), &host, &port);
        QString str = QString("[%1:%2] %3").arg(host.toString()).arg(port).arg(QString(data));

        ui->txtMain->setTextColor(QColor("red"));
        ui->txtMain->append(str);
    }
}

//4. Send UDP data (socket - > connecttohost)
//  In the connect button, obtain the manually entered server IP address and port number
void UdpClinet::on_btnSend_clicked()
{
    UdpServerIP = ui->txtServerIP->text().trimmed();
    UdpServerPort = ui->txtServerPort->text().trimmed().toInt();

    QString data = ui->cboxData->currentText();
    if (data.length() <= 0) {
        return;
    }

    QByteArray buffer = data.toUtf8();

    socket->writeDatagram(buffer, QHostAddress(UdpServerIP), UdpServerPort);

    QString str = QString("[send out:%1:%2] %3").arg(UdpServerIP).arg(UdpServerPort).arg(data);

    ui->txtMain->setTextColor(QColor("darkgreen"));
    ui->txtMain->append(str);
}


udpclinet.h

#ifndef UDPCLINET_H
#define UDPCLINET_H

#include <QWidget>
#include <QtNetwork>

namespace Ui {
class UdpClinet;
}

class UdpClinet : public QWidget
{
    Q_OBJECT

public:
    explicit UdpClinet(QWidget *parent = nullptr);
    void initForm();
    ~UdpClinet();

private:
    Ui::UdpClinet *ui;
    QUdpSocket *socket;

    QString UdpServerIP;         
    int UdpServerPort;

private slots:
    void readData();

private slots:
    void on_btnSend_clicked();
};

#endif // UDPCLINET_H

2, UDP server

The demonstration of using UDP server communication in Qt is as follows:

● practical operation flow chart


● code

udpserver.cpp

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

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

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

//1. ui
//2. Initialization
//① Create QUdpSocket socket object
//② Establish a signal slot (readyRead) for socket to receive buffered data
void UdpServer::initForm()
{
    socket = new QUdpSocket(this);
    connect(socket, SIGNAL(readyRead()), this, SLOT(readData()));
}

//3. Enable listening. The IP address is not specified and the port is customized
void UdpServer::on_btnListen_clicked()
{
    UdpServerPort = ui->txtListenPort->text().trimmed().toInt();
    if (ui->btnListen->text() == "monitor") {
        if (socket->bind(QHostAddress::AnyIPv4, UdpServerPort)) {
            ui->btnListen->setText("close");
        }
    } else {
        socket->abort();
        ui->btnListen->setText("monitor");
    }
}

//4. Receive UDP client data, obtain UDP client IP and port number, and save them to listWidget
void UdpServer::readData()
{
    QHostAddress host;
    quint16 port;
    QByteArray data;

    while (socket->hasPendingDatagrams()) {
        data.resize(socket->pendingDatagramSize());
        socket->readDatagram(data.data(), data.size(), &host, &port);

        //ip
        QString ip = host.toString();
        ip = ip.replace("::ffff:", "");
        if (ip.isEmpty()) {
            continue;
        }

        QString str = QString("[%1:%2] %3").arg(ip).arg(port).arg(QString(data));
        ui->txtMain->setTextColor(QColor("red"));
        ui->txtMain->append(str);

        //Add to listWidget list
        QString listData = QString("%1:%2").arg(ip).arg(port);
        for (int i = 0; i < ui->listWidget->count(); i++) {
            QString s = ui->listWidget->item(i)->text();
            if (listData == s) {
                return;
            }
        }
        ui->listWidget->addItem(listData);
        ui->labCount->setText(QString("%1 Clients").arg(ui->listWidget->count()));
    }
}

//5. Send data to UDP client
//   Send with saved client IP and port number
void UdpServer::on_btnSend_clicked()
{
    QString data = ui->cboxData->currentText();
    if (data.length() <= 0) {
        return;
    }

    int row = ui->listWidget->currentRow();
    if (row >= 0) {
        QString str = ui->listWidget->item(row)->text();
        QStringList list = str.split(":");
        QString ip = list.at(0);
        quint16 port = list.at(1).toInt();

        socket->writeDatagram(data.toUtf8(), QHostAddress(ip), port);

        QString strPrint = QString("[%1:%2] %3").arg(ip).arg(port).arg(data);
        ui->txtMain->setTextColor(QColor("darkgreen"));
        ui->txtMain->append(strPrint);
    }
}


udpserver.h

#ifndef UDPSERVER_H
#define UDPSERVER_H

#include <QWidget>
#include <QtNetwork>

namespace Ui {
class UdpServer;
}

class UdpServer : public QWidget
{
    Q_OBJECT

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

private:
    Ui::UdpServer *ui;
    QUdpSocket *socket;
    int UdpServerPort;

private slots:
    void readData();

private slots:
    void on_btnListen_clicked();
    void on_btnSend_clicked();
};

#endif // UDPSERVER_H

Source code:      NetToolsTest

For other QT Widge articles, please click here:      QT Widget learning notes

Sister articles:      Introduction and practice of Qt TCP/UDP network protocol (I) TCP communication

Posted by jalperin on Mon, 18 Oct 2021 10:46:00 -0700