Qt读取DSP通过以太网发送的UDP报文

        基于 QudpSocket类编写的上位机,用于接收dsp的数据,内容如下。

      

         可以看到要实现实现接收UDP报文有两步,一是使用bind()绑定地址和端口,二是调用redatagram()或者receivedatagram()接收报文。关于第二步,每当数据报文到达时,会发出readyread()信号且此时haspengingDataGrams()会返回true。

        上代码

        widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QUdpSocket>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

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

private slots:
    void Device_info_readyRead();

    void on_pushButton_bind_clicked();

private:
    Ui::Widget *ui;
    QUdpSocket *udpSocket_net;
};
#endif // WIDGET_H

widget.c

        由于是单播通信,所以就直接再代码中固定IP与端口了.上位机IP:192.169.0.54,端口:8080。需要注意的是由于发送端是按照16进制发送,而非按照ascii发送,所以在将报文输出在textedit中需要按照16进制显示。 即ui->dataLabel->insertPlainText(dataGram.toHex()+"\n");否则由于数值超过了127将无法正常显示。

#include "widget.h"
#include "ui_widget.h"
#include <QUdpSocket>
#include <QDebug>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);  //初始化界面
    ui->dataLabel->setReadOnly(true);//textedit设置为只读

    udpSocket_net = new QUdpSocket;

}

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


void Widget::Device_info_readyRead()
{
    while(udpSocket_net->hasPendingDatagrams())
    {
        QByteArray dataGram;
        QHostAddress tempHost("192.168.0.54"); 
        quint16 port = 28000;

        dataGram.resize(udpSocket_net->pendingDatagramSize());   //读取的数据报大小
        qDebug() << "开始监听:数据长度为" << dataGram.size() << endl;
        udpSocket_net->readDatagram(dataGram.data(),dataGram.size(),&tempHost,&port);//读取下位机udp数据
        ui->dataLabel->insertPlainText(dataGram.toHex()+"\n");//按16进制显示在dataLabel中

    }
}

bool bindviewflag=0;
void Widget::on_pushButton_bind_clicked()
{
    if (bindviewflag==0)
    {
        bindviewflag=1;
        if(true == udpSocket_net->bind(QHostAddress("192.168.0.54"), 8080, QAbstractSocket::ShareAddress))
        {
             qDebug() << "绑定成功" << endl;
             connect(udpSocket_net,SIGNAL(readyRead()),this,SLOT(Device_info_readyRead()));//连接信号与槽
             ui->pushButton_bind->setText("关闭网络");
        }
    }
    else
    {
        udpSocket_net->close();
        ui->pushButton_bind->setText("打开网络");
        bindviewflag=0;
    }

}

ui界面,有点简陋:)

 测试结果:

这里我让dsp每个控制周期发送的变量都为常数(1,2,3,4,5),每30个控制周期发送一次,一个浮点数是4个字节,4*5*30对应报文的长度是600,与调试的结果一致。

       再附上一段QT的自写大小端转换的函数,用于将16进制浮点数按照大端读取。两个for循环是因为我的下位机28388,会将每个控制周期的变量值进行排序,每30个控制周期发送一次。所以写了两个for循环解码,代码如下:

int num=5;
float *ptr=new float[num*30];   //动态数组用于存放解码后的数据,动态数组的大小
void Widget::hex_to_single()    //网络报文解码函数
{
    int i,j;

    for(i=0;i<30;i++){
        for(j=0;j<num;j++){
            QByteArray getdata=dataGram.toHex().mid(i*num*8+j*8,8); //获取对应的数值
            qDebug()<<"字符串"<< getdata <<endl;
            quint32 value = getdata.toUInt(0,16);  //将字符串转换为数值 注意必须得转成uint
            qDebug()<<value<<endl;
            quint32 value2 = qToBigEndian(value); //小端字节序转大端字节序
            qDebug()<<value2<<endl;
            float b =*(float*)&value2;  //转换为single类型
            ptr[j*30+i]=b;
            qDebug()<<ptr[j*30+i]<<endl;
        }
    }
}

        追更:应该是QUdpSocket类与windows兼容度不够,超过1kHz的报文就接收不到了。追求更高的抓包速率推荐调用winpcap或npcap库。

QT以太网通信UDP是一种基于用户数据报协议(UDP)的通信方式。在QT中,可以使用QUdpSocket类来实现UDP通信。通过使用QUdpSocket类的相关方法和信号槽机制,可以实现在不同主机之间进行数据的传输和通信。 在QT中,可以通过引入network模块并在.pro文件中加入相应的代码来启用UDP通信功能。使用QUdpSocket类可以创建一个UDP套接字,其中目标端口使用QSpinBox组件,目标IP使用QLineEdit组件,接收框使用PlainTextEdit组件。通过绑定相应的槽函数,可以实现当套接字准备好读取数据时触发相应的事件。可以使用on_pushButton_clicked()槽函数来实现点击按钮时发送数据的功能。通过getLocalIP()函数可以获取本机的IP地址。 对于UDP通信的具体实现代码,请参考文末的代码链接。 需要注意的是,为了保证UDP通信的成功,需要确保IP地址和端口号的正确设置,并避免与其他程序或设备占用相同的端口号。在单机测试时,可以开启两个QT应用,一个用于发送数据,一个用于接收数据。在多机使用时,需要保证发送端和接收端处于同一网段,并使用接收端的IP地址进行设置。 总结起来,QT以太网通信UDP是一种基于UDP协议的通信方式,通过QUdpSocket类和相关的Qt组件可以实现在不同主机之间进行数据的传输和通信。具体的实现代码请参考文末提供的链接。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [QT下的UDP通信](https://blog.csdn.net/weixin_42454651/article/details/127137758)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值