zoukankan      html  css  js  c++  java
  • 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();
    }
    
    
  • 相关阅读:
    Python的if判断与while循环
    python基础之数据类型与变量
    网络基础之网络协议篇
    操作系统简介
    计算机基础之计算机硬件系统
    从头开始编写一个Orchard网上商店模块(3)
    从头开始编写一个Orchard网上商店模块(2)
    从头开始编写一个Orchard网上商店模块(1)
    var和dynamic的区别及如何正确使用dynamic ?
    [DOM Event Learning] Section 3 jQuery事件处理基础 on(), off()和one()方法使用
  • 原文地址:https://www.cnblogs.com/Doyoung/p/13252631.html
Copyright © 2011-2022 走看看