How To receive 198 bytes data into structure through UDP communication in QT
-
I have a data which is 198 bytes starting with 2 byte header next 8 bytes DI data and so on.... How do I convert the datagram which I have received into my structure . And by default the datagram which is received is in Qbytearray???
-
#pragma pack(push,1)
typedef union BufDouble {
struct {
double n[12];
};
char b[sizeof(double) * 12];
} BUF_DOUBLE;
#pragma pack(pop)
BUF_DOUBLE bufdouble;
udpSocket = new QUdpSocket(this);
connect(udpSocket, &QUdpSocket::readyRead, this, &MainWindow::readPendingDatagrams);
void MainWindow::readPendingDatagrams()
{
while (udpSocket->hasPendingDatagrams()) {
QNetworkDatagram datagram = udpSocket->receiveDatagram();
qDebug() << datagram.data().count();
if(datagram.data().count()) {
memcpy(&bufdouble.b[0], datagram.data(), sizeof(double) * 12);
}
}
} -
For testing purpose, I am getting data from Hercules... I am doing correct?
-
@HimanshuKaushik You can simply define a struct describing your package and then cast the pointer returned by https://doc.qt.io/qt-5/qbytearray.html#data-1
struct Datagram { int16_t header; int64_t DI; ... } Datagram *datagram = reinterpret_cast<Datagram*>(data.data());
Keep in mind that you can get in trouble with endeanness, depending on how the data is encoded before sending.
-
@HimanshuKaushik said in How To receive 198 bytes data into structure through UDP communication in QT:
I am doing correct?
How should we know? You did not show a single line of code...
-
@jsulm said in How To receive 198 bytes data into structure through UDP communication in QT:
Keep in mind that you can get in trouble with endeanness, depending on how the data is encoded before sending.
you may also get problems with padding!
How do I convert the datagram which I have received into my structure . And by default the datagram which is received is in Qbytearray???
first make sure, you actually have enough bytes, UDP packages may or may not contain all 198 bytes at once, and may or may not get lost in transmission.
I personally would suggest creating a custom QDataStream << and >> operator that works with your struct.
or a setter/constructor that accepts a QByteArray and a getter that returns a QByteArray.
-
@jsulm Yes I have made the structure like this, but did not know how to use. I will try this. I am posting previous code below so that can I get better feedback , if made silly mistakes in it.
I will explain the process below this code with picturemainwindow.h file
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QUdpSocket> typedef struct{ unsigned short header; unsigned char diData[8]; }test; 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 connection(); void on_pushButton_clicked(); private: Ui::MainWindow *ui; QUdpSocket *socket; QHostAddress host_address; quint16 host_port; }; #endif // MAINWINDOW_H
Mainwindow.cpp file
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QHostAddress> #include <QDebug> #include<QByteArray> #define localaddress QHostAddress("192.168.1.167") #define port 5000 test test_data; MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); host_address= QHostAddress("192.168.1.167"); host_port=1234; socket = new QUdpSocket(this); socket->bind(localaddress, port); connect(socket, SIGNAL(readyRead()), this, SLOT(connection())); } MainWindow::~MainWindow() { delete ui; } void MainWindow::connection() { while(socket->hasPendingDatagrams()) { QByteArray datagram; datagram.resize(socket->pendingDatagramSize()); QHostAddress sender; quint16 senderport; socket->readDatagram(datagram.data(),datagram.size(), &sender, &senderport); QString message = datagram.toHex(); qDebug() << message; qDebug() << size; } }
so this was basic code to get the UDP data. Now I am sending 10 bytes from hercules. You can see I am getting the whole data in the Qdebug but how do i get that into my structure , That my point.
-
#pragma pack(push,1)
typedef union BufDouble {
struct {
double n[12];
};
char b[sizeof(double) * 12];
} BUF_DOUBLE;
#pragma pack(pop)
BUF_DOUBLE bufdouble;
udpSocket = new QUdpSocket(this);
connect(udpSocket, &QUdpSocket::readyRead, this, &MainWindow::readPendingDatagrams);
void MainWindow::readPendingDatagrams()
{
while (udpSocket->hasPendingDatagrams()) {
QNetworkDatagram datagram = udpSocket->receiveDatagram();
qDebug() << datagram.data().count();
if(datagram.data().count()) {
memcpy(&bufdouble.b[0], datagram.data(), sizeof(double) * 12);
}
}
}