单播、组播、广播、工具开发、QT Udp通讯协议开发简介及开发工具源码

欢迎小伙伴的点评✨✨,相互学习、互关必回、全天在线🍳🍳🍳
博主🧑🧑 本着开源的精神交流Qt开发的经验、将持续更新续章,为社区贡献博主自身的开源精神👩‍🚀
已更新 UDP_family APP2.0版本


前言

Qt Creator是一个用于Qt开发的轻量级跨平台集成开发环境。Qt Creator可带来两大关键益处:提供首个专为支持跨平台开发而设计的集成开发环境 (IDE),并确保首次接触Qt框架的开发人员能迅速上手和操作。即使不开发Qt应用程序,Qt Creator也是一个简单易用且功能强大的IDE。
许多应用只支持UDP,如:多媒体数据流,不产生任何额外的数据,即使知道有破坏的包也不进行重发。当强调传输性能而不是传输的完整性时,如:音频和多媒体应用,UDP是最好的选择。在数据传输时间很短,以至于此前的连接过程成为整个流量主体的情况下,UDP也是一个好的选择。


一、UDP 单播、组播、广播。

1.1单播

  • 信息的接收和传递只在两个节点之间进行
  • 在同一个网段从一个发端传递到一个收端

1.2 组播

  • 组播一般通过组播IP地址来实现。组播IP地址就是D类IP地址,即224.0.0.0至239.255.255.255之间的IP地址。
  • 通过组播的方法,发送端把数据传递到一个组播IP地址,接收端通过加入组播的方法抓取信息。

1.3 广播

  • 在IP网络中,广播地址用IP地址“255.255.255.255”来表示,这个IP地址代表同一子网内所有的IP地址。
  • 通过地址255,向对整个网段(1~255)发送信息如果处理不好会引起网络风暴。

二、单播、组播、广播、工具开发源码及效果图如下

图一

在这里插入图片描述

图二

在这里插入图片描述

2.1注意事项如图所示

在这里插入图片描述
需要在工程xxx.pro文件中加入

QT       +=network

UDP_family 开发工程源码如下

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QMainWindow>
#include <QPushButton>
#include <QLineEdit>
#include <QLabel>
#include <QGridLayout>
#include <QDebug>
#include <QTextEdit>
#include <QUdpSocket>
#include <QTime>
#include <QLine>
#include <QNetworkDatagram>
#include <QComboBox>
#include <QByteArray> //字节转换16进制

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = nullptr);
    ~Widget();

private:
    Ui::Widget *ui;
public:
void mylayout();

protected:

QComboBox   *box;
QComboBox   *m_box;
QComboBox   *g_box;

QLine       *Line;
QLine       *Line_1;

QPushButton *button_1;
QPushButton *button_2;
QPushButton *button_3;
QPushButton *button_4;
QPushButton *button_5;


QPushButton *m_button_1;
QPushButton *m_button_2;
QPushButton *m_button_3;
QPushButton *m_button_4;
QPushButton *m_button_5;


QPushButton *g_button_1;
QPushButton *g_button_2;
QPushButton *g_button_3;
QPushButton *g_button_4;
QPushButton *g_button_5;


QLineEdit   *edit_1;
QLineEdit   *edit_2;
QLineEdit   *edit_3;
QLineEdit   *edit_4;
QLineEdit   *edit_5;


QLineEdit   *m_edit_1;
QLineEdit   *m_edit_2;
QLineEdit   *m_edit_3;
QLineEdit   *m_edit_4;
QLineEdit   *m_edit_5;




QLineEdit   *g_edit_1;
QLineEdit   *g_edit_2;
QLineEdit   *g_edit_3;
QLineEdit   *g_edit_4;
QLineEdit   *g_edit_5;


QLabel       *x_bel_1;
QLabel       *x_bel_2;
QLabel       *x_bel_3;

QLabel       *bel_1;
QLabel       *bel_2;
QLabel       *bel_3;
QLabel       *bel_4;
QLabel       *bel_5;
QLabel       *bel_6;

QLabel       *m_bel_1;
QLabel       *m_bel_2;
QLabel       *m_bel_3;
QLabel       *m_bel_4;
QLabel       *m_bel_5;
QLabel       *m_bel_6;


QLabel       *g_bel_1;
QLabel       *g_bel_2;
QLabel       *g_bel_3;
QLabel       *g_bel_4;
QLabel       *g_bel_5;
QLabel       *g_bel_6;

QTextEdit    *Text_1;
QTextEdit    *m_Text_1;
QTextEdit    *g_Text_1;

QGridLayout *layout;

private slots:   //单播
void button_1_clicked();
void button_2_clicked();
void button_3_clicked();
void button_4_clicked();
void button_5_clicked();

void receiveData();
void parseData(QString &str1);


QString Byte2Acsii(uchar *Data,int iLength);
private slots: //组播
void reayRead_on();
void on_pushButton_1clicked();
void on_pushButton_2clicked();
void on_pushButton_3clicked();
void on_pushButton_4clicked();
void on_pushButton_5clicked();


private slots: //广播

void g_button_1_clicked();
void g_button_2_clicked();
void g_button_3_clicked();
void g_button_4_clicked();
void g_button_5_clicked();
void processData();

private:   //单播QUdoSocket
QUdpSocket  *m_sender;
QUdpSocket  *m_receiver;


private:   //广播QUdoSocket
QUdpSocket  *g_sender;
QUdpSocket  *g_receiver;

private:   //组播QUdpSocket
QUdpSocket*  udpSocket;
QHostAddress groupAddress;

private:  //单播使用的变量
 qint16 port_1;
 qint16 port;
 QString ip;
 QString strdata;
 QString box_data;
 QString str_16;
 QString str3;
 QByteArray hex_bytes;
private:   //组播使用的变量
QString m_str;
QString m_ip;
qint16 m_port;
qint16 m_port_1;
QString m_box_data;


private:   //广播使用的变量
QString g_str;
QString g_ip;
qint16 g_port;
qint16 g_port_1;
QString g_box_data;
private:
int type_a;
int m_type_a;
int g_type_a;


};

#endif // WIDGET_H

main.cpp

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

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

widget.cpp

#include "widget.h"
#include "ui_widget.h"


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

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

void Widget::mylayout()
{

    m_sender = new QUdpSocket(this);
    m_receiver =new QUdpSocket(this);

    g_sender = new QUdpSocket(this);
    g_receiver = new QUdpSocket(this);

    connect(g_receiver,&QUdpSocket::readyRead,this,&Widget::processData); //广播

    connect(m_receiver,&QUdpSocket::readyRead,this,&Widget::receiveData); //单播



    udpSocket = new QUdpSocket(this);
    connect(udpSocket ,&QUdpSocket::readyRead,this,&Widget::reayRead_on);  //组播

    box    = new QComboBox;
    m_box  = new QComboBox;
    g_box  = new QComboBox;

    x_bel_1 = new QLabel("单播工具");
    x_bel_2 = new QLabel("组播工具");
    x_bel_3 = new QLabel("广播工具");



    edit_1 = new QLineEdit;   //输入 端口 ip 数据
    edit_2 = new QLineEdit;   //ip
    edit_3 = new QLineEdit;    //数据
    edit_4 = new QLineEdit;   //本地端口
    edit_5 = new QLineEdit;   //16进制接收字节

    m_edit_1 = new QLineEdit;   //输入 端口
    m_edit_2 = new QLineEdit;   //输入 端口 ip
    m_edit_3 = new QLineEdit;   //输入 本地端口
    m_edit_4 = new QLineEdit;   //输入 端口  数据
    m_edit_5 = new QLineEdit;   //输入 端口  数据

    g_edit_1 = new QLineEdit;   //输入 端口
    g_edit_2 = new QLineEdit;   //输入 端口 ip
    g_edit_3 = new QLineEdit;   //输入 本地端口
    g_edit_4 = new QLineEdit;   //输入 端口  数据
    g_edit_5 = new QLineEdit;   //输入 端口  数据


    bel_1  = new QLabel("设置目标端口:");
    bel_2  = new QLabel("设置目标地址:");
    bel_3  = new QLabel("设置本地端口:");
    bel_4  = new QLabel("数据传输:");
    bel_5  = new QLabel("设置字符格式:");
    bel_6  = new QLabel("设置接收字节:");


    m_bel_1  = new QLabel("设置目标端口:");
    m_bel_2  = new QLabel("设置目标地址:");
    m_bel_3  = new QLabel("设置本地端口:");
    m_bel_4  = new QLabel("数据传输:");
    m_bel_5  = new QLabel("设置字符格式");
    m_bel_6  = new QLabel("设置接收字节:");

    g_bel_1  = new QLabel("设置目标端口:");
    g_bel_2  = new QLabel("设置目标地址:");
    g_bel_3  = new QLabel("设置本地端口:");
    g_bel_4  = new QLabel("数据传输:");
    g_bel_5  = new QLabel("设置字符格式");
    g_bel_6  = new QLabel("设置接收字节:");


    button_1 = new QPushButton("设置信息");
    button_2 = new QPushButton("绑定本地端口");
    button_3 = new QPushButton("单播发送");
    button_4 = new QPushButton("解除绑定本地端口");
    button_5 = new QPushButton("清除接收的数据");

    m_button_1 = new QPushButton("设置信息");
    m_button_2 = new QPushButton("绑定本地端口");
    m_button_3 = new QPushButton("组播发送");
    m_button_4 = new QPushButton("解除绑定本地端口");
    m_button_5 = new QPushButton("清除接收的数据");


    g_button_1 = new QPushButton("设置信息");
    g_button_2 = new QPushButton("绑定本地端口");
    g_button_3 = new QPushButton("广播发送");
    g_button_4 = new QPushButton("解除绑定本地端口");
    g_button_5 = new QPushButton("清除接收的数据");

    Text_1  =  new QTextEdit;
    m_Text_1 = new QTextEdit;
    g_Text_1 = new QTextEdit;

    button_1->setMinimumHeight(50);
    button_2->setMinimumHeight(50);
    button_3->setMinimumHeight(50);
    button_4->setMinimumHeight(50);
    button_5->setMinimumHeight(50);

    Text_1->setMinimumHeight(100);
    m_Text_1->setMinimumHeight(100);
    g_Text_1->setMinimumHeight(100);

    m_button_1->setMinimumHeight(50);
    m_button_2->setMinimumHeight(50);
    m_button_3->setMinimumHeight(50);
    m_button_4->setMinimumHeight(50);
    m_button_5->setMinimumHeight(50);

    g_button_1->setMinimumHeight(50);
    g_button_2->setMinimumHeight(50);
    g_button_3->setMinimumHeight(50);
    g_button_4->setMinimumHeight(50);
    g_button_5->setMinimumHeight(50);



    layout = new QGridLayout(this);

    QFont font("Microsoft YaHei", 14, 75);
    //font.setPointSize(14);
    x_bel_1->setFont(font);
    x_bel_2->setFont(font);
    x_bel_3->setFont(font);

    layout->addWidget(x_bel_1,0,0);
    layout->addWidget(x_bel_2,0,5);
    layout->addWidget(x_bel_3,0,10);



    layout->addWidget(bel_1,1,0);
    layout->addWidget(bel_2,2,0);
    layout->addWidget(bel_3,3,0);
    layout->addWidget(bel_4,4,0);
    layout->addWidget(bel_5,8,0);
    layout->addWidget(bel_6,8,2);

    layout->addWidget(edit_1,1,1,1,3);
    layout->addWidget(edit_2,2,1,1,3);
    layout->addWidget(edit_3,3,1,1,3);
    layout->addWidget(edit_4,4,1,1,3);
    layout->addWidget(edit_5,8,3);

    layout->addWidget(button_1,5,0);
    layout->addWidget(button_2,5,1);
    layout->addWidget(button_3,5,2);
    layout->addWidget(button_4,5,3);
    layout->addWidget(button_5,6,0,1,4);//(x,y,长,宽)

    layout->addWidget(Text_1,7,0,1,4);



    connect(button_1,SIGNAL(clicked(bool)),this,SLOT(button_1_clicked()));
    connect(button_2,SIGNAL(clicked(bool)),this,SLOT(button_2_clicked()));
    connect(button_3,SIGNAL(clicked(bool)),this,SLOT(button_3_clicked()));
    connect(button_4,SIGNAL(clicked(bool)),this,SLOT(button_4_clicked()));
    connect(button_5,SIGNAL(clicked(bool)),this,SLOT(button_5_clicked()));



    connect(m_button_1,SIGNAL(clicked(bool)),this,SLOT(on_pushButton_1clicked()));
    connect(m_button_2,SIGNAL(clicked(bool)),this,SLOT(on_pushButton_2clicked()));
    connect(m_button_3,SIGNAL(clicked(bool)),this,SLOT(on_pushButton_3clicked()));
    connect(m_button_4,SIGNAL(clicked(bool)),this,SLOT(on_pushButton_4clicked()));
    connect(m_button_5,SIGNAL(clicked(bool)),this,SLOT(on_pushButton_5clicked()));


    connect(g_button_1,SIGNAL(clicked(bool)),this,SLOT(g_button_1_clicked()));
    connect(g_button_2,SIGNAL(clicked(bool)),this,SLOT(g_button_2_clicked()));
    connect(g_button_3,SIGNAL(clicked(bool)),this,SLOT(g_button_3_clicked()));
    connect(g_button_4,SIGNAL(clicked(bool)),this,SLOT(g_button_4_clicked()));
    connect(g_button_5,SIGNAL(clicked(bool)),this,SLOT(g_button_5_clicked()));




    //画竖线
    QFrame *line = new QFrame();
    QFrame *line_1 = new QFrame();

    line->setFrameShape(QFrame::VLine);  //HLine 是横线  VLine 是竖线
    line->setFrameShadow(QFrame::Plain);

    line_1->setFrameShape(QFrame::VLine);  //HLine 是横线  VLine 是竖线
    line_1->setFrameShadow(QFrame::Plain);
     //line->raise();//顶层展示
    layout->addWidget(line,0,4,8,4);

    layout->addWidget(line_1,0,9,8,4);

    //画组播
    layout->addWidget(m_edit_1,1,6,1,3);
    layout->addWidget(m_edit_2,2,6,1,3);
    layout->addWidget(m_edit_3,3,6,1,3);
    layout->addWidget(m_edit_4,4,6,1,3);
    layout->addWidget(m_edit_5,8,8);

    layout->addWidget(m_bel_1,1,5);
    layout->addWidget(m_bel_2,2,5);
    layout->addWidget(m_bel_3,3,5);
    layout->addWidget(m_bel_4,4,5);
    layout->addWidget(m_bel_5,8,5);
    layout->addWidget(m_bel_6,8,7);

    layout->addWidget(m_button_1,5,5);
    layout->addWidget(m_button_2,5,6);
    layout->addWidget(m_button_3,5,7);
    layout->addWidget(m_button_4,5,8);
    layout->addWidget(m_button_5,6,5,1,4);

    layout->addWidget(m_Text_1,7,5,1,4);

    box->addItem("toUtf8");
    box->addItem("16");

    m_box->addItem("toUtf8");
    m_box->addItem("16");

    g_box->addItem("toUtf8");
    g_box->addItem("16");

    layout->addWidget(g_box,8,11);
    layout->addWidget(m_box,8,6);
    layout->addWidget(box,8,1);

    layout->addWidget(g_edit_1,1,11,1,3);
    layout->addWidget(g_edit_2,2,11,1,3);
    layout->addWidget(g_edit_3,3,11,1,3);
    layout->addWidget(g_edit_4,4,11,1,3);
    layout->addWidget(g_edit_5,8,13);


    layout->addWidget(g_bel_1,1,10);
    layout->addWidget(g_bel_2,2,10);
    layout->addWidget(g_bel_3,3,10);
    layout->addWidget(g_bel_4,4,10);
    layout->addWidget(g_bel_5,8,10);
    layout->addWidget(g_bel_6,8,12);

    layout->addWidget(g_button_1,5,10);
    layout->addWidget(g_button_2,5,11);
    layout->addWidget(g_button_3,5,12);
    layout->addWidget(g_button_4,5,13);
    layout->addWidget(g_button_5,6,10,1,4);

    layout->addWidget(g_Text_1,7,10,1,4);




}




void Widget::button_1_clicked()   //设置信息
{

    box_data = box->currentText();

    qDebug()<<box_data;
    type_a= edit_5->text().toInt();
    port = edit_1->text().toInt();
    ip = edit_2->text();

    Text_1->append("设置信息成功!");


}



void Widget::button_2_clicked()  //绑定本地端口
{
    port_1 = edit_3->text().toInt();
    m_receiver->bind(port_1);
    Text_1->append("绑定本地端口!");
}

void Widget::button_3_clicked()  //单播发送
{
    if(box_data=="toUtf8")
    {    strdata = edit_4->text().toUtf8();
         m_sender->writeDatagram(strdata.toUtf8(),QHostAddress(ip),port);
         Text_1->append( "发送成功!");
    }
    if(box_data=="16")
    {

        bool ok;

        strdata = edit_4->text();
        int length = strdata.size()/3+1;
        uchar  array[length];

        for(int i = 0; i<=length; i++)
        {


              array[i] =  (uchar) strdata.mid(i*3,2).toUInt(&ok,16);


        }
        char *p = (char *)array;
        m_sender->writeDatagram(p,length ,QHostAddress(ip),port);
        Text_1->append( "发送成功!");

    }



}

void Widget::button_4_clicked()  //解除绑定本地端口
{
    m_receiver->abort();
    Text_1->append("解除绑定本地端口成功!");
}

void Widget::button_5_clicked()  //清除接收的shuju
{
    Text_1->clear();
    Text_1->append("清除成功!");
}



void Widget::receiveData()
{
      char buf[type_a];
      memset(buf,0,sizeof(buf));
      QHostAddress  cliAddr;  //用于存储接收的ip地址
      quint16 port_2;           //用于存储接收的端口地址

    qint64 len = m_receiver-> readDatagram(buf, sizeof(buf), &cliAddr, &port_2);
      if(len > 0)
      {


          QTime  cur_time = QTime::currentTime();
          QString time_info = cur_time.toString("hh:mm:ss");

          QString  str1 =cliAddr.toString() ;
          parseData(str1);

          QString str = QString("接收到的IP是%1\n接收到的端口是%2\n接收的数据%3\n当前时间是%4\n")
                  .arg(str1)
                  .arg(port_2)
                  .arg(buf)
                  .arg(time_info);

          if(box_data=="toUtf8")
          {
              Text_1->append(str.toUtf8());/*按照append 的格式留到text输出有滑条*/

          }
          if(box_data=="16")
          {

              uchar *p = (uchar *)buf;

              Text_1->append(Byte2Acsii(p, sizeof(buf)));
          }


     }
}


/*组播区*/



void Widget::on_pushButton_1clicked()
{
    m_box_data = m_box->currentText();
    m_str =m_edit_4->text().toUtf8();
    m_ip = m_edit_2->text();
    m_port =m_edit_1->text().toInt();
    m_port_1 = m_edit_3->text().toInt();
    m_type_a = m_edit_5->text().toInt();

    m_Text_1->append( "设置信息成功!");
}
void Widget::on_pushButton_2clicked()
{
    if(udpSocket->state() != QAbstractSocket::BoundState)                                                                  // 判断是否绑定绑定端口
    {
        bool ret = udpSocket->bind(QHostAddress::AnyIPv4, m_port_1, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint);                                       // 使用组播时这里必须要指定AnyIPv4,不指定将会默认Any,加入组播会失败
                                                                                                                             // 绑定绑定接收数据的端口,一般用组播端口
                                                                                                                                 // ShareAddress允许一台电脑上多个程序绑定同一个端口,便于测试,但是在windows下需要加上ReuseAddressHint才有效
        if(ret)
        {
            qInfo() << "绑定本地地址成功!";
            ret = udpSocket->joinMulticastGroup(QHostAddress(m_ip));           // 加入组播组
            if(ret)
            {
                m_Text_1->append( "加入组播组成功,绑定端口成功!");

            }
            else
            {
                m_Text_1->append( "加入组播组失败!");
                m_Text_1->append( "请检查是否设置信息和是否输入加入的组播地址,请解除绑定端口,重新设置信息!");
            }
        }
        else
        {
            m_Text_1->append( "绑定本地地址失败!");
        }
    }
    else
    {
        m_Text_1->append( "udpSocket 打开失败!");
    }


}




void  Widget::on_pushButton_3clicked()
{
    qint16 len = udpSocket->writeDatagram(m_str.toUtf8(),QHostAddress(m_ip),m_port);
    //qInfo()<<QString("发送数据长度:%1").arg(len);
    m_Text_1->append( "发送成功!");
}

void  Widget::on_pushButton_4clicked()
{
    udpSocket->abort();
    m_Text_1->append( "解除绑定成功!");
}

void  Widget::on_pushButton_5clicked()
{
    m_Text_1->clear();
    m_Text_1->append( "清除成功!");
}

void Widget::reayRead_on()
{

    QHostAddress  cliAddr;  //用于存储接收的ip地址
    quint16 port_2;           //用于存储接收的端口地址
    char buf[m_type_a];
    memset(buf,0,sizeof(buf));
    qint64 len = udpSocket-> readDatagram(buf, sizeof(buf), &cliAddr, &port_2);


    if(len > 0)
    {


        QTime  cur_time = QTime::currentTime();
        QString time_info = cur_time.toString("hh:mm:ss");

        QString  str1 =cliAddr.toString() ;
        parseData(str1);

        QString str = QString("接收到的IP是%1\n接收到的端口是%2\n接收的数据%3\n当前时间是%4\n")
                .arg(str1)
                .arg(port_2)
                .arg(buf)
                .arg(time_info);

        if(m_box_data=="toUtf8")
        {
            m_Text_1->append(str.toUtf8());/*按照append 的格式留到text输出有滑条*/

        }
        if(m_box_data=="16")
        {

            uchar *p = (uchar *)buf;  //强制转换使用指针 char 转换 unsigned char

            m_Text_1->append(Byte2Acsii(p, sizeof(buf)));

        }

    }
}




/********广播*******/
void Widget::g_button_1_clicked()
{
    g_box_data = g_box->currentText();
    g_ip = g_edit_2->text();
    g_port = g_edit_1->text().toInt();
    g_port_1 = g_edit_3->text().toInt();
    g_type_a = g_edit_5->text().toInt();
    g_Text_1->append( "设置信息成功!");
}

void Widget::g_button_2_clicked()
{
    g_receiver->bind(g_port_1,QUdpSocket::ShareAddress);
    g_Text_1->append( "绑定本地端口成功!");
}

void Widget::g_button_3_clicked()
{
    if(g_box_data=="toUtf8")
   {
        g_str =g_edit_4->text().toUtf8();
        g_sender->writeDatagram(g_str.toUtf8(),QHostAddress(g_ip),g_port);
        g_Text_1->append( "发送成功!");
   }

    if(g_box_data=="16")
    {
        g_str =g_edit_4->text();
        bool ok;
        int length = g_str.size()/3+1;
        uchar  array[length];

        for(int i = 0; i<=length; i++)
        {


              array[i] =  (uchar) g_str.mid(i*3,2).toUInt(&ok,16);


        }
        char *p = (char *)array;
        g_sender->writeDatagram(p,QHostAddress(g_ip),g_port);
        g_Text_1->append( "发送成功!");

    }

}

void Widget::g_button_4_clicked()
{
    g_receiver->abort();
    g_Text_1->append("解除绑定本地端口成功!");
}

void Widget::g_button_5_clicked()
{
    g_Text_1->clear();
    g_Text_1->append("清除成功!");
}

void Widget::processData()
{
    char buf[g_type_a];
    memset(buf,0,sizeof(buf));
    QHostAddress  cliAddr;  //用于存储接收的ip地址
    quint16 port_2;           //用于存储接收的端口地址
    qint64 len = g_receiver-> readDatagram(buf, sizeof(buf), &cliAddr, &port_2);


    if(len > 0)
    {


        QTime  cur_time = QTime::currentTime();
        QString time_info = cur_time.toString("hh:mm:ss");

        QString  str1 =cliAddr.toString() ;
        parseData(str1);

        QString str = QString("接收到的IP是%1\n接收到的端口是%2\n接收的数据%3\n当前时间是%4\n")
                .arg(str1)
                .arg(port_2)
                .arg(buf)
                .arg(time_info);

        if(g_box_data=="toUtf8")
        {
            g_Text_1->append(str.toUtf8());/*按照append 的格式留到text输出有滑条*/
             qDebug()<<"b";
        }
        if(g_box_data=="16")
        {
             uchar *p = (uchar *)buf;
            g_Text_1->append(Byte2Acsii(p, sizeof(buf)));

        }


   }
}


/********************Qstring 转16进制***************************/
QString Widget::Byte2Acsii(uchar *Data,int iLength)
{
    QString ST="",strT;
    int iB,iS;
    char cB,cS;

    //---
    for (int i=0;i<iLength;i++)
    {
       iB = *(Data+i)/16;
       if (iB>=10)
       {
          cB = 'A' + (iB-10);
       }
       else
          cB = '0' + iB;

       iS = *(Data+i)%16;
       if (iS >= 10)
       {
          cS = 'A' + (iS-10);
       }
       else
          cS = '0' + iS;
       strT=QString("%1%2 ").arg(cB).arg(cS);
       ST += strT;
    }
    return ST;
}


/*********清除字节当中多余的字符***********/

void Widget::parseData(QString &str1)
{
    char array[]={'f',':'}; //需要去除的字符
    int length = sizeof (array)/sizeof (char);
    for(int i=0;i<length;i++)
    {
        QString tmp = QString(array[i]);
        if(str1.contains(tmp))
        {
           str1 =str1.replace(tmp,"");
        }
    }
}


三、旧版本 UDP_family 1.0 工程开发原文件压缩包

工程文件解压直接导入即可,0C币下载

四、Qt 项目UDP_family更新2.0版本改动和效果图如下

升级功能1:从原来的一个平面操作界面升级为堆栈窗口可选择性界面
升级功能2:原先使用发送整型16进制丢数据现象已经解决
代码优化:完成了,单播,组播,广播,代码的可维护性,及单元测试。

图一
在这里插入图片描述
图二
在这里插入图片描述
图三
在这里插入图片描述
图四
在这里插入图片描述

五、代码逻辑详解

下面介绍基千 UDP 的经典编程模型, UDP 客户端与服务器间的交互时序如图 5.1 所示 。
可以看出,在 UDP 方式下,客户端并不与服务器建立连接,它只负责调用发送函数向服务
器发出数据报。类似地,服务器也不从客户端接收连接,只负责调用接收函数,等待来自某客
户端的数据到达。
Qt 中通过 QUdpSocket 类实现 UDP 协议的编程。下面通过一个实例,介绍如何实现基于
UDP 的广播应用,它由 UDP 服务器和 UDP 客户端两部分组成。
图5.1
在这里插入图片描述

5.1、UDP客户端详解

初始化套接字

QUdpSocket *Dsender = new QUdpSocket(this);

发送

Dsender->writeDatagram(Ddata_C.toUtf8(),QHostAddress(DIP_F),Dport_F);

其中,Ddata_C.toUtf8()是char型字符串、QHostAddress(DIP_F)是发送目标的IP、Dport_F是发送目标的端口。
发送字符串【例1】

Dsender->writeDatagram("123",QHostAddress(127.0.0.1),2222);

代码解析:表达使用2222端口向127.0.0.1发送字符串123

发送整型【例2】

Dsender->writeDatagram(data_p,length ,QHostAddress(DIP_F),Dport_F);

其中,与发送字符串的变动是增加了整型字节长度(length),如果不增加字节长度,会默认未字符串形式,当遇到某一字节位0时,会结束发送剩下的数据。
/******************************************************************************************************************/

5.2、UDP服务器详解

初始化套接字

QUdpSocket Dreceiver = new QUdpSocket(this);

绑定

 Dreceiver->bind(Dport_S);           //绑定接收端口

代码解析:绑定端口用于筛选,接收到的数据;当接收到的数据端口为我们设置的端口时可以监听

接收

 connect(Dreceiver,&QUdpSocket::readyRead,this,&danbo::DreceiveData); //单播 
     QHostAddress  cliAddr;  //用于存储接收的ip地址
      quint16 port_2;           //用于存储接收的端口地址
Dreceiver-> readDatagram(buf, sizeof(buf), &cliAddr, &port_2);

代码解析:connect接口的作用是连接QIODevice的readyRead()信号。QUdpSocket 也是一个I/O设备,从QIODevice继承而来,当有数据到达I/O设备时,发出readyRead()信号。DreceiveData()函数响应QUdpSocket的readyRead()信号,一旦Dreceiver对象中有数据可读时,即通过readDatagram()方法将数据读出并显示。

六,工程文件原码已经上传GIthub

git bash直接命令拉取即可

git clone https://github.com/dhn111/Qt.git
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

东.'

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值