QT下UDP套接字通信——QUdpSocket 簡單使用


QT下UDP套接字通信——QUdpSocket

  1. QUdpSocket類提供一個UDP套接字。
  2. UDP(用戶數據報協議)是一種輕量級、不可靠、面向數據報、無連接的協議。它可以在可靠性不重要的情況下使用。QUdpSocket是QAbstractSocket的一個子類,允許您發送和接收UDP數據報。
  3. 注意:使用時需要在pro文件中添加network組件
QT       += network

例子

效果展示

代碼
  1. 發送端

.h

#ifndef SENDWIDGET_H
#define SENDWIDGET_H
#include "QPushButton"
#include "QLineEdit"

#include <QWidget>
#include <QUdpSocket>

class SendWIdget : public QWidget
{
    Q_OBJECT
public:
    explicit SendWIdget(QWidget *parent = nullptr);
    ~SendWIdget();

private slots:
    void slo_sendMessge();

private:
    void init();


private:
    QLineEdit * edit;
    QPushButton * btn;

    QUdpSocket * sender;
};

#endif // SENDWIDGET_H

.cpp

#include "SendWIdget.h"

#include <QHBoxLayout>
#include <QTextCodec>

SendWIdget::SendWIdget(QWidget *parent) : QWidget(parent)
{
    // 初始化
    init();
    // 關聯發送按鈕的點擊信號
    connect(btn,&QPushButton::clicked,this,&SendWIdget::slo_sendMessge);

}

SendWIdget::~SendWIdget()
{
    delete edit;
    delete btn;
    delete sender;
}

void SendWIdget::slo_sendMessge()
{
    // 獲取輸入框的內容
    QString string(edit->text());
    qDebug() << string;
    /*發送數據
     * 第一個參數:要發送的內容,這里是要發送輸入框的內容,
     *             參數沒有QString類型,需要轉換為QByteArray類型或Char*類型
     * 第二個參數:要發送到的目標IP地址,這里是本機測試,所以用LocalHost
     * 第三個參數:要發送的的目標端口,自己隨意指定
     * 返回值:發送成功返回發送的字節數,失敗返回-1
     */
    int w = sender->writeDatagram(string.toLocal8Bit(),QHostAddress::LocalHost,8179);
    // 判斷是否發送成功
    if(w == -1)
    {
        qDebug() << "發送失敗!";
    }
    else
    {
        qDebug() << "發送成功,字節數:" << w;
    }
}

/*
 * 初始化界面和通信套接字
 */
void SendWIdget::init()
{
    edit = new QLineEdit;
    btn = new QPushButton("發送");
    // 創建水平布局
    QHBoxLayout * layout = new QHBoxLayout(this);
    // 將行文本框添加到水平布局中
    layout->addWidget(edit);
    // 將發送按鈕添加到水平布局
    layout->addWidget(btn);

    // 初始化UDP套接字
    sender = new QUdpSocket(this);
}

main

#include "widget.h"
#include "SendWIdget.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    SendWIdget s;
    s.setWindowTitle("send");
    s.show();

    return a.exec();
}

  1. 接收端

.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QPlainTextEdit>
#include <QUdpSocket>

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = 0);
    ~Widget();
private slots:
    void slo_receiveMeaage();

private:
    QPlainTextEdit * showMessage;

    QUdpSocket * receiver;

};

#endif // WIDGET_H

.cpp

#include "widget.h"

#include <QDebug>
#include <QTextCodec>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    // 創建顯示消息的文本框
    showMessage = new QPlainTextEdit(this);
    // 設置文本框只讀
    showMessage->setReadOnly(true);
    // 設置文本框初始大小
    showMessage->resize(300,200);

    // 創建UDP套接字
    receiver = new QUdpSocket(this);
    // 綁定接收信息的IP和端口
    receiver->bind(QHostAddress::LocalHost,8179);

    // 關聯readyRead信號(每當有新的數據可以從設備的當前讀取通道讀取時,這個信號就會發出一次)
    connect(receiver,&QUdpSocket::readyRead,this,&Widget::slo_receiveMeaage);
}

Widget::~Widget()
{
    delete showMessage;
    delete receiver;
}

void Widget::slo_receiveMeaage()
{
    // 用於存儲接收到的數據
    QByteArray message;

    // 循環讀取接收的數據,如果至少有一個數據報等待讀取,些函數返回 true,否則返回 false。
    while (receiver->hasPendingDatagrams())
    {
        // 動態設置大小為第一個掛起的 udp 數據包的大小
        message.resize(receiver->pendingDatagramSize());
        /* 接收數據
         * 第一個參數:存儲接收到數據
         * 第二個參數:接收的數據最大的大小
         * 返回值:成功返回接收的數據字節數,失敗返回-1
         */
        int r = receiver->readDatagram(message.data(),message.size());
        // 判斷是否接收成功
        if(r == -1)
        {
            qDebug() << "接收數據失敗";
        }
        else
        {
            qDebug() << "接收數據成功";
        }
    }
    //指定編碼方式,否則如果數據中出現中文,會出現亂碼情況
    QTextCodec *codec = QTextCodec::codecForName("GBK");
    QString string = codec->toUnicode(message);
    qDebug() << string;
    // 將編碼后的數據顯示到文本框中
    showMessage->appendPlainText(string);
}

main

#include "widget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();

    return a.exec();
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM