Qt TCP/UDP 网络协议入门实操UDP通讯

Posted 火山上的企鹅

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Qt TCP/UDP 网络协议入门实操UDP通讯相关的知识,希望对你有一定的参考价值。

文章目录



GitHub 源码:     QWidgetLearningPro 选择 NetTools

QT Widge 其它文章请点击这里:     QT Widget 学习笔记


姊妹篇:     

Qt TCP/UDP 网络协议入门实操(一)TCP通讯

Qt TCP/UDP 网络协议入门实操(二)UDP通讯

Qt TCP/UDP 网络协议入门实操(补充)

此文只是最简单的入门学习,需进一步可以看 飞扬青云 大佬的源码 QWidgetDemo, 选择 nettool ,已经是非常完善的网络调试助手了


UDP(User Datagram Protocol即用户数据报协议)是一个轻量级的,不可靠的,面向数据报的无连接协议。我们现在几乎每个人都使用的QQ,其聊天时就是使用UDP协议进行消息发送的。就像QQ那样,当有很多用户,发送的大部分都是短消息,要求能及时响应,并且对安全性要求不是很高的情况下使用UDP协议。在选择使用协议的时候,选择UDP必须要谨慎。在网络质量令人十分不满意的环境下,UDP协议数据包丢失会比较严重。但是由于UDP的特性:它不属于连接型协议,因而具有资源消耗小,处理速度快的优点,所以通常音频、视频和普通数据在传送时使用UDP较多,因为它们即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。所以qq这种对保密要求并不太高的聊天程序就是使用的UDP协议。

在Qt中提供了QUdpSocket 类来进行UDP数据报(datagrams)的发送和接收。这里我们还要了解一个名词Socket,也就是常说的“套接字”。Socket简单地说,就是一个IP地址加一个port端口 。因为我们要传输数据,就要知道往哪个机子上传送,而IP地址确定了一台主机,但是这台机子上可能运行着各种各样的网络程序,我们要往哪个程序中发送呢?这时就要使用一个端口来指定UDP程序。所以说,Socket指明了数据报传输的路径。

此段摘自:浅谈 Qt 中 UDP 之 UdpSocket通信实例

一、UDP 客户端

在Qt 中使用UDP 客户端通讯演示如下:

● 实操流程图

● 代码

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. 初始化
//① 创建 QTcpSocket 套接字对象
//② 建立socket 接收缓冲数据的信号槽(readyRead)
void UdpClinet::initForm()

    socket = new QUdpSocket(this);
    connect(socket, SIGNAL(readyRead()), this, SLOT(readData()));


//3. 接收UDP数据
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. 发送UDP数据 (socket->connectToHost)
//  在连接按键中,获取手动输入的服务器IP地址和端口号
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("[发送:%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

二、UDP 服务器

在Qt 中使用UDP 服务器通讯演示如下:

● 实操流程图


● 代码

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. 初始化
//① 创建 QUdpSocket 套接字对象
//② 建立socket 接收缓冲数据的信号槽(readyRead)
void UdpServer::initForm()

    socket = new QUdpSocket(this);
    connect(socket, SIGNAL(readyRead()), this, SLOT(readData()));


//3.开启监听, IP不指定,端口自定义
void UdpServer::on_btnListen_clicked()

    UdpServerPort = ui->txtListenPort->text().trimmed().toInt();
    if (ui->btnListen->text() == "监听") 
        if (socket->bind(QHostAddress::AnyIPv4, UdpServerPort)) 
            ui->btnListen->setText("关闭");
        
     else 
        socket->abort();
        ui->btnListen->setText("监听");
    


//4. 接收UDP客户端数据,获取UDP客户端IP和端口号,并保存到 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);

        //添加到 listWidget 列表中
        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个客户端").arg(ui->listWidget->count()));
    


//5. 发送数据到UDP客户端
//   利用已保存的客户端IP和端口号发送
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

源码:     NetToolsTest

QT Widge 其它文章请点击这里:     QT Widget 学习笔记


姊妹篇:     

Qt TCP/UDP 网络协议入门实操(一)TCP通讯

Qt TCP/UDP 网络协议入门实操(二)UDP通讯

Qt TCP/UDP 网络协议入门实操(补充)


以上是关于Qt TCP/UDP 网络协议入门实操UDP通讯的主要内容,如果未能解决你的问题,请参考以下文章

Qt TCP/UDP 网络协议入门实操UDP通讯

Qt TCP/UDP 网络协议入门实操TCP通讯

Qt TCP/UDP 网络协议入门实操TCP通讯

Qt TCP/UDP 网络协议入门实操TCP通讯

Qt TCP/UDP 网络协议入门实操(补充)

Qt TCP/UDP 网络协议入门实操(补充)