Qt中QUdpSocket類的簡(jiǎn)單使用詳解
QUdpSocket類的簡(jiǎn)單使用
下面我們用一個(gè)做一個(gè)簡(jiǎn)單的例子。
一、發(fā)送端
發(fā)送端界面:

發(fā)送端代碼:
.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QUdpSocket>
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_btnUnicast_clicked();
void on_btnBoardcast_clicked();
private:
Ui::MainWindow *ui;
QUdpSocket* m_pSender = nullptr;
};
#endif // MAINWINDOW_H.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QHostAddress>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
m_pSender = new QUdpSocket(this);
}
MainWindow::~MainWindow()
{
delete ui;
delete m_pSender;
}
void MainWindow::on_btnUnicast_clicked()
{
QString strText = ui->lineEdit->text();
if(strText.isEmpty())
return;
QHostAddress host("127.0.0.1");
quint16 nPort = 8888;
qint64 nSend = m_pSender->writeDatagram(strText.toUtf8(),host,nPort);
if(nSend == -1)
{
qDebug() << "單播發(fā)送失敗" << m_pSender->errorString();
}
else
{
qDebug() << "單播發(fā)送成功,字節(jié)數(shù)" << nSend;
}
}
void MainWindow::on_btnBoardcast_clicked()
{
QString strText = ui->lineEdit->text();
if(strText.isEmpty())
return;
quint16 nPort = 8888;
qint64 nSend = m_pSender->writeDatagram(strText.toUtf8(),QHostAddress::Broadcast,nPort);
if(nSend == -1)
{
qDebug() << "廣播發(fā)送失敗" << m_pSender->errorString();
}
else
{
qDebug() << "廣播發(fā)送成功,字節(jié)數(shù)" << nSend;
}
}二、接收端
接受端的界面,比較簡(jiǎn)單:

接受端代碼如下:
.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QUdpSocket>
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
public slots:
void ReadDatagram();
private:
Ui::MainWindow *ui;
QUdpSocket* m_pReceiver;
};
#endif // MAINWINDOW_H.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
m_pReceiver = new QUdpSocket(this);
quint16 listenPort = 8888;
// 綁定端口:QHostAddress::Any 表示監(jiān)聽所有網(wǎng)卡的該端口(支持本機(jī)/局域網(wǎng)/外網(wǎng))
bool bBind = m_pReceiver->bind(QHostAddress::Any,listenPort);
if(!bBind)
{
ui->textEdit->append("綁定端口失?。? + m_pReceiver->errorString());
}
else
{
ui->textEdit->append("已綁定端口 " + QString::number(listenPort) + ",等待接收數(shù)據(jù)...");
}
// 綁定接收數(shù)據(jù)信號(hào):當(dāng)有數(shù)據(jù)到達(dá)時(shí)觸發(fā)readyRead()
connect(m_pReceiver,&QUdpSocket::readyRead,this,&MainWindow::ReadDatagram);
}
MainWindow::~MainWindow()
{
delete ui;
delete m_pReceiver;
}
void MainWindow::ReadDatagram()
{
// 循環(huán)讀取所有待處理的數(shù)據(jù)包(可能同時(shí)有多個(gè))
while (m_pReceiver->hasPendingDatagrams())
{
QByteArray datagram;
// 預(yù)留足夠的緩沖區(qū)(根據(jù)數(shù)據(jù)包大小調(diào)整,這里設(shè)為1024)
datagram.resize(m_pReceiver->pendingDatagramSize());
QHostAddress senderIp; // 發(fā)送方IP
quint16 senderPort; // 發(fā)送方端口
// 讀取數(shù)據(jù)包,同時(shí)獲取發(fā)送方的IP和端口
qint64 readBytes = m_pReceiver->readDatagram(
datagram.data(),
datagram.size(),
&senderIp,
&senderPort
);
if (readBytes == -1)
{
ui->textEdit->append("接收失?。? + m_pReceiver->errorString());
continue;
}
// 解析并顯示數(shù)據(jù)
QString recvData = QString::fromUtf8(datagram);
QString log = QString("[%1:%2] 接收數(shù)據(jù):%3")
.arg(senderIp.toString())
.arg(senderPort)
.arg(recvData);
ui->textEdit->append(log);
}
}代碼說(shuō)明:
- 核心類
QUdpSocket:- 發(fā)送:
writeDatagram()直接發(fā)送數(shù)據(jù)包,無(wú)需建立連接,這是 UDP “無(wú)連接” 的核心體現(xiàn); - 接收:綁定端口后,通過(guò)
readyRead()信號(hào)監(jiān)聽數(shù)據(jù),readDatagram()讀取數(shù)據(jù)并獲取發(fā)送方信息; - 廣播:
QHostAddress::Broadcast是 UDP 獨(dú)有的能力,TCP 無(wú)法實(shí)現(xiàn)。
- 發(fā)送:
- 綁定端口的參數(shù):
QHostAddress::Any:監(jiān)聽所有網(wǎng)卡的指定端口,支持接收來(lái)自本機(jī)、局域網(wǎng)其他設(shè)備的 UDP 數(shù)據(jù);- 若僅監(jiān)聽本機(jī),可用
QHostAddress::LocalHost(127.0.0.1)。
- 數(shù)據(jù)編碼:
- 用
toUtf8()/fromUtf8()轉(zhuǎn)換QString和QByteArray,保證跨平臺(tái)編碼一致性,避免中文亂碼。
- 用
- 對(duì)比 TCP 的簡(jiǎn)化點(diǎn):
- UDP 無(wú)需調(diào)用
connectToHost()建立連接,也無(wú)需處理connected()/disconnected()信號(hào); - 無(wú)需處理粘包:
pendingDatagramSize()可獲取單個(gè)數(shù)據(jù)包的大小,一次讀取即可,而 TCP 需自定義協(xié)議拆包。
- UDP 無(wú)需調(diào)用
項(xiàng)目運(yùn)行結(jié)果:

到此這篇關(guān)于Qt中QUdpSocket類的簡(jiǎn)單使用的文章就介紹到這了,更多相關(guān)Qt QUdpSocket類使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
c++ STL set_difference set_intersection set_union 操作
這篇文章主要介紹了c++ STL set_difference set_intersection set_union 操作,需要的朋友可以參考下2017-03-03
C++進(jìn)階異常處理與智能指針實(shí)戰(zhàn)指南
本文詳解C++異常處理與智能指針,解決錯(cuò)誤傳遞冗余和資源泄漏問(wèn)題,強(qiáng)調(diào)自定義異常體系、RAII思想及智能指針類型選擇,提升代碼可靠性與可維護(hù)性,感興趣的朋友跟隨小編一起看看吧2025-10-10
用Visual Studio2017寫C++靜態(tài)庫(kù)圖文詳解
這篇文章主要介紹了用Visual Studio2017寫C++靜態(tài)庫(kù)的圖文教程,需要的朋友可以參考下2017-04-04
QT5實(shí)現(xiàn)TTS文本語(yǔ)音朗讀功能
TTS?語(yǔ)音朗讀?是開發(fā)中常用的功能,Qt已經(jīng)給封裝完成,我們只需要調(diào)用即可,本文就為大家介紹了QT5如何調(diào)用實(shí)現(xiàn)文本朗讀功能的,需要的可以參考一下2023-05-05
算法之排序算法的算法思想和使用場(chǎng)景總結(jié)
這篇文章主要介紹了算法之排序算法的算法思想和使用場(chǎng)景總結(jié),本文講解了插入排序、交換排序、選擇排序等幾大類排序算法的特點(diǎn)、思想和使用場(chǎng)景,需要的朋友可以參考下2014-08-08
C++進(jìn)程的創(chuàng)建和進(jìn)程ID標(biāo)識(shí)詳細(xì)介紹
傳統(tǒng)的C++(C++98)中并沒有引入線程這個(gè)概念。linux和unix操作系統(tǒng)的設(shè)計(jì)采用的是多進(jìn)程,進(jìn)程間的通信十分方便,同時(shí)進(jìn)程之間互相有著獨(dú)立的空間,不會(huì)污染其他進(jìn)程的數(shù)據(jù),天然的隔離性給程序的穩(wěn)定性帶來(lái)了很大的保障2022-08-08
C語(yǔ)言深入講解之從函數(shù)棧幀角度理解return關(guān)鍵字
在C語(yǔ)言中,一般情況下函數(shù)的返回值是通過(guò)函數(shù)中的return語(yǔ)句來(lái)實(shí)現(xiàn)的,每調(diào)用一次return語(yǔ)句只能從函數(shù)中返回一個(gè)值,這篇文章主要給大家介紹了關(guān)于C語(yǔ)言從函數(shù)棧幀角度理解return關(guān)鍵字的相關(guān)資料,需要的朋友可以參考下2021-09-09

