Results 1 to 7 of 7

Thread: transfer struct data on udpSocket

  1. #1
    Join Date
    Jan 2019
    Posts
    11
    Thanks
    4
    Qt products
    Qt5 Qt/Embedded
    Platforms
    Unix/X11

    Default transfer struct data on udpSocket

    hello community,

    i am new in this forum and in qt I need your help to finish my program.
    i am writing a c++ code with the IDE Qt for my project.
    i have two separately classes, that communicate on updsocket. One class(SendObjects) send data on port 50885 and the second class(receiveObjects) receive this data on port 50885. The data to send are of type struct. In both classes i have declared a structure type, called mDataChannels with 6 elements: Channel_Nr, AC_Volt, DC_Volt,etc...
    Now on my socket with port 50885 from class "SendObjects", i want to send simultaneously 40 objects of typ structure(mDataChannels) and then receive this all objects(or all elements of this) on the other class names "receiveObjects".
    i tried to write a code with and without QVector but it doesn't work fine. I need help to improve my code. i don't have error but i cannot read something. I don't too know if my class "SendObjects" or my class "receiveObjects" really work fine. I have added a new QDataStream Operator. may be it is wrong.

    SendObject.h
    Qt Code:
    1. #ifndef MAINWINDOW_H
    2. #define MAINWINDOW_H
    3.  
    4. #include <QMainWindow>
    5. #include <QUdpSocket>
    6. #include <QTimer>
    7. #include <QDateTime>
    8. #include <vector>
    9. #include <QString>
    10. #include <QDebug>
    11. #include <QVector>
    12.  
    13. namespace Ui {
    14. class MainWindow;
    15. }
    16.  
    17. struct mDataChannels
    18. {
    19. QString mmyChannel_Nr;
    20. float mAC_Volt;
    21. float mDC_Volt;
    22. float mAC_Current;
    23. float mDC_Current;
    24. float mmPotential;
    25. };
    26.  
    27. class MainWindow : public QMainWindow
    28. {
    29. Q_OBJECT
    30.  
    31. public:
    32. explicit MainWindow(QWidget *parent = 0);
    33. ~MainWindow();
    34.  
    35. friend QDataStream& operator << (QDataStream &stream, const QVector<mDataChannels> &_DataTest);
    36.  
    37. private slots:
    38. void sendTestData();
    39.  
    40. private:
    41. Ui::MainWindow *ui;
    42. QUdpSocket *testUdpSocket;
    43. QTimer *testTimer;
    44. QVector < mDataChannels > _DataTest, temp;
    45. };
    46.  
    47. #endif // MAINWINDOW_H
    To copy to clipboard, switch view to plain text mode 
    ,

    SendObject.cpp

    Qt Code:
    1. #include "mainwindow.h"
    2. #include "ui_mainwindow.h"
    3.  
    4. MainWindow::MainWindow(QWidget *parent) :
    5. QMainWindow(parent),
    6. ui(new Ui::MainWindow)
    7. {
    8. ui->setupUi(this);
    9. testUdpSocket = new QUdpSocket(this);
    10. _DataTest.resize(40);
    11. temp.resize(40);
    12. for(int i = 0; i < 40; i++)
    13. {
    14. _DataTest[i].mmyChannel_Nr = tr("Kanal ") +QString::number(i + 1);
    15. _DataTest[i].mAC_Volt = 150.320 + (float)i;
    16. _DataTest[i].mDC_Volt = 80.67 + (float)i;
    17. _DataTest[i].mAC_Current = 5.0 + (float)i/10;
    18. _DataTest[i].mDC_Current = 3.0 + (float)i/10;
    19. _DataTest[i].mmPotential = 6.0 + (float)i/2;
    20. }
    21.  
    22.  
    23. testTimer = new QTimer(this);
    24. connect(testTimer, SIGNAL(timeout()), this, SLOT(sendTestData()));
    25. testTimer->start(2 * 1000);
    26.  
    27.  
    28. }
    29.  
    30. MainWindow::~MainWindow()
    31. {
    32. delete ui;
    33. }
    34.  
    35.  
    36. QDataStream& operator << (QDataStream &stream, QVector<mDataChannels> &_DataTest)
    37. {
    38. _DataTest.resize(40);
    39. QDateTime dataTime;
    40. stream << dataTime;
    41. for(int i = 0; i < 40; i++)
    42. stream << (QString)_DataTest[i].mmyChannel_Nr << static_cast<float>(_DataTest[i].mAC_Volt)
    43. << static_cast<float>(_DataTest[i].mDC_Volt) << static_cast<float>(_DataTest[i].mAC_Current)
    44. << static_cast<float>(_DataTest[i].mDC_Current) << static_cast<float>(_DataTest[i].mmPotential);
    45. return stream;
    46. }
    47.  
    48.  
    49. void MainWindow::sendTestData()
    50. {
    51.  
    52. QByteArray myTestSendData;
    53. QDataStream stream(&myTestSendData, QIODevice::WriteOnly);
    54. stream.setVersion(QDataStream::Qt_5_9);
    55. stream << QDateTime::currentDateTime();
    56. for(int i = 0; i < 40; i++)
    57. stream << _DataTest[i].mmyChannel_Nr << _DataTest[i].mAC_Volt
    58. << _DataTest[i].mDC_Volt << _DataTest[i].mAC_Current
    59. << _DataTest[i].mDC_Current << _DataTest[i].mmPotential;
    60. testUdpSocket->writeDatagram(myTestSendData, QHostAddress::LocalHost, 50885);
    61. }
    To copy to clipboard, switch view to plain text mode 

    receiveObjects.h

    Qt Code:
    1. #ifndef MAINWINDOW_H
    2. #define MAINWINDOW_H
    3.  
    4. #include <QMainWindow>
    5. #include <QUdpSocket>
    6. #include <QTimer>
    7. #include <QDebug>
    8. #include <QDateTime>
    9.  
    10. namespace Ui {
    11. class MainWindow;
    12. }
    13.  
    14. struct DataChannels
    15. {
    16. QString myChannel_Nr;
    17. float AC_Volt;
    18. float DC_Volt;
    19. float AC_Current;
    20. float DC_Current;
    21. float mPotential;
    22.  
    23. };
    24.  
    25. class MainWindow : public QMainWindow
    26. {
    27. Q_OBJECT
    28.  
    29. public:
    30. explicit MainWindow(QWidget *parent = 0);
    31. ~MainWindow();
    32. friend QDataStream& operator >> (QDataStream &stream, QVector <DataChannels> &receivePacket);
    33.  
    34. private slots:
    35. void readAllValue();
    36.  
    37. private:
    38. Ui::MainWindow *ui;
    39. QUdpSocket *readSocket;
    40. QVector < DataChannels > receivePacket;
    41. };
    42.  
    43. #endif // MAINWINDOW_H
    To copy to clipboard, switch view to plain text mode 
    ,

    receiveObjects.cpp

    Qt Code:
    1. #include "mainwindow.h"
    2. #include "ui_mainwindow.h"
    3.  
    4. MainWindow::MainWindow(QWidget *parent) :
    5. QMainWindow(parent),
    6. ui(new Ui::MainWindow)
    7. {
    8. ui->setupUi(this);
    9.  
    10. readSocket = new QUdpSocket(this);
    11. readSocket->bind(QHostAddress::LocalHost, 50885);
    12. receivePacket.resize(40);
    13. connect(readSocket, SIGNAL(readyRead()), this, SLOT(readAllValue()));
    14. }
    15.  
    16. MainWindow::~MainWindow()
    17. {
    18. delete ui;
    19. }
    20.  
    21. QDataStream& operator >>(QDataStream &stream, QVector<DataChannels> &receivePacket)
    22. {
    23. QDateTime mDateTime;
    24. quint32 tempInt;
    25. QString tempString;
    26. receivePacket.resize(40);
    27.  
    28. stream >> mDateTime;
    29. for(int i = 0; i < 40; i++)
    30. {
    31. stream >> tempString; receivePacket[i].myChannel_Nr = tempString;
    32. stream >> tempInt; receivePacket[i].AC_Volt = tempInt;
    33. stream >> tempInt; receivePacket[i].DC_Volt = tempInt;
    34. stream >> tempInt; receivePacket[i].AC_Current = tempInt;
    35. stream >> tempInt; receivePacket[i].DC_Current = tempInt;
    36. stream >> tempInt; receivePacket[i].mPotential = tempInt;
    37. }
    38. return stream;
    39. }
    40.  
    41. void MainWindow::readAllValue()
    42. {
    43. QByteArray mReceiveDatagram;
    44.  
    45. do
    46. {
    47. mReceiveDatagram.resize(int(readSocket->pendingDatagramSize()));
    48. readSocket->readDatagram(mReceiveDatagram.data(), mReceiveDatagram.size());
    49. } while(readSocket->hasPendingDatagrams());
    50.  
    51. QDateTime dateTime;
    52. QDataStream stream(&mReceiveDatagram, QIODevice::ReadOnly);
    53. stream.setVersion(QDataStream::Qt_5_9);
    54. stream >> dateTime;
    55. for(int i = 0; i< 40; i++)
    56. {
    57. stream >> receivePacket[i].myChannel_Nr >> receivePacket[i].AC_Volt >> receivePacket[i].DC_Volt
    58. >> receivePacket[i].AC_Current >> receivePacket[i].DC_Current >> receivePacket[i].mPotential;
    59. }
    60. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by malone; 17th January 2019 at 12:40.

  2. #2
    Join Date
    Jan 2019
    Posts
    11
    Thanks
    4
    Qt products
    Qt5 Qt/Embedded
    Platforms
    Unix/X11

    Default Re: transfer struct data on udpSocket

    nobody helps me

  3. #3
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: transfer struct data on udpSocket

    Do you have a test, e.g. unittest, that checks for serialization and deserialization without any network involvement?

    Do you receive datagrams?

    Any reason you discard all datagrams but the last?

    Your stream operators aren't used so they can't really be the problem.

    If your goal is to use them in a later stage of your program, you should probably rethink using a hard coded magic number (40) when looping :-)

    Cheers,
    _

  4. #4
    Join Date
    Jan 2019
    Posts
    11
    Thanks
    4
    Qt products
    Qt5 Qt/Embedded
    Platforms
    Unix/X11

    Default Re: transfer struct data on udpSocket

    thank you already for your answer,

    Quote Originally Posted by anda_skoa View Post
    Do you have a test, e.g. unittest, that checks for serialization and deserialization without any network involvement?

    _
    i don't have. i only started both programs(SendObject and ReceiveObject). Normally , the class sendObject is for serialization of my struct Object and the class ReceiveObject is for deserialization, i th thought so. Maybe it's my code that was badly written.

    Quote Originally Posted by anda_skoa View Post
    Do you receive datagrams? _
    i don't receive anything. i tried to sniff my network with wireshark, something is sent that i cannot read or receive on my Class receiveObject.

    Quote Originally Posted by anda_skoa View Post
    Any reason you discard all datagrams but the last?_
    i want to send all datagrams, that is the goal of my program. i didn't know that i discard all datagrams except the last

    Quote Originally Posted by anda_skoa View Post
    Your stream operators aren't used so they can't really be the problem._
    How to use it?

    Quote Originally Posted by anda_skoa View Post
    If your goal is to use them in a later stage of your program, you should probably rethink using a hard coded magic number (40) when looping :-)_
    i didn't understand what do you mean? normally with my class "sendObject" i want to send 40 object of type struct on the socket. One object of this struct contains 6 elements.

    I written a simple program that send only one Object of type struct and receives it. It works fine. i can receive something that i send but i have to send every element of my object of type struct.
    So now if i want to send 40 objects of type struct containing each 6 elements, i have to send element by element. That's long. That's why i wanted to integrate a QVector that i cannot send and read.

    thank you already for your answer,

    Quote Originally Posted by anda_skoa View Post
    Do you have a test, e.g. unittest, that checks for serialization and deserialization without any network involvement?

    _
    i don't have. i only started both programs(SendObject and ReceiveObject). Normally , the class sendObject is for serialization of my struct Object and the class ReceiveObject is for deserialization, i th thought so. Maybe it's my code that was badly written.

    Quote Originally Posted by anda_skoa View Post
    Do you receive datagrams? _
    i don't receive anything. i tried to sniff my network with wireshark, something is sent that i cannot read or receive on my Class receiveObject.

    Quote Originally Posted by anda_skoa View Post
    Any reason you discard all datagrams but the last?_
    i want to send all datagrams, that is the goal of my program. i didn't know that i discard all datagrams except the last

    Quote Originally Posted by anda_skoa View Post
    Your stream operators aren't used so they can't really be the problem._
    How to use it?

    Quote Originally Posted by anda_skoa View Post
    If your goal is to use them in a later stage of your program, you should probably rethink using a hard coded magic number (40) when looping :-)_
    i didn't understand what do you mean? normally with my class "sendObject" i want to send 40 object of type struct on the socket. One object of this struct contains 6 elements.

    I written a simple program that send only one Object of type struct and receives it. It works fine. i can receive something that i send but i have to send every element of my object of type struct.
    So now if i want to send 40 objects of type struct containing each 6 elements, i have to send element by element. That's long. That's why i wanted to integrate a QVector that i cannot send and read.


    Added after 6 minutes:


    this is my simple code to send and receice element by element of an object of type struct

    send.h

    Qt Code:
    1. namespace Ui {
    2. class MainWindow;
    3. }
    4.  
    5. struct DataChannels
    6. {
    7. QString myChannel_Nr;
    8. float AC_Volt;
    9. float DC_Volt;
    10. float AC_Current;
    11. float DC_Current;
    12. float Potential;
    13. };
    14.  
    15.  
    16. class MainWindow : public QMainWindow
    17. {
    18. Q_OBJECT
    19.  
    20. public:
    21. explicit MainWindow(QWidget *parent = 0);
    22. ~MainWindow();
    23. private slots:
    24. void sendTestData();
    25.  
    26. void on_pushButton_clicked();
    27.  
    28. private:
    29. Ui::MainWindow *ui;
    30. QUdpSocket *testUdpSocket;
    31. QTimer *testTimer;
    32. DataChannels mData, temp;
    33. };
    34.  
    35. #endif // MAINWINDOW_H
    To copy to clipboard, switch view to plain text mode 

    send.cpp

    Qt Code:
    1. MainWindow::MainWindow(QWidget *parent) :
    2. QMainWindow(parent),
    3. ui(new Ui::MainWindow)
    4. {
    5. ui->setupUi(this);
    6. testUdpSocket = new QUdpSocket(this);
    7.  
    8.  
    9.  
    10. mData.myChannel_Nr = tr("Kanal ") +QString::number(1);
    11. mData.AC_Volt = 150.320;
    12. mData.DC_Volt = 80.67;
    13. mData.AC_Current = 5.0;
    14. mData.DC_Current = 3.0;
    15. mData.Potential = 6.0;
    16. temp = mData;
    17.  
    18.  
    19. testTimer = new QTimer(this);
    20. connect(testTimer, SIGNAL(timeout()), this, SLOT(sendTestData()));
    21. testTimer->start(200);
    22.  
    23.  
    24. }
    25.  
    26. MainWindow::~MainWindow()
    27. {
    28. delete ui;
    29. }
    30.  
    31.  
    32.  
    33. void MainWindow::sendTestData()
    34. {
    35.  
    36. QByteArray myTestSendData;
    37. QDataStream stream(&myTestSendData, QIODevice::WriteOnly);
    38. stream.setVersion(QDataStream::Qt_5_9);
    39. stream << QDateTime::currentDateTime() << mData.myChannel_Nr << mData.AC_Volt
    40. << mData.DC_Volt << mData.AC_Current << mData.DC_Current << mData.Potential;
    41. testUdpSocket->writeDatagram(myTestSendData, QHostAddress::LocalHost, 50885);
    42.  
    43.  
    44. }
    45.  
    46. void MainWindow::on_pushButton_clicked()
    47. {
    48. QMainWindow::close();
    49. }
    To copy to clipboard, switch view to plain text mode 

    receive.h

    Qt Code:
    1. namespace Ui {
    2. class MainWindow;
    3. }
    4.  
    5. struct DataChannels
    6. {
    7. QString myChannel_Nr;
    8. float AC_Volt;
    9. float DC_Volt;
    10. float AC_Current;
    11. float DC_Current;
    12. float Potential;
    13.  
    14. };
    15.  
    16. class MainWindow : public QMainWindow
    17. {
    18. Q_OBJECT
    19.  
    20. public:
    21. explicit MainWindow(QWidget *parent = 0);
    22. ~MainWindow();
    23.  
    24. private slots:
    25. void readAllValue();
    26.  
    27. private:
    28. Ui::MainWindow *ui;
    29. QUdpSocket *readSocket;
    30. DataChannels readPacket;
    31. };
    32.  
    33. #endif // MAINWINDOW_H
    To copy to clipboard, switch view to plain text mode 

    receive.cpp
    Qt Code:
    1. MainWindow::MainWindow(QWidget *parent) :
    2. QMainWindow(parent),
    3. ui(new Ui::MainWindow)
    4. {
    5. ui->setupUi(this);
    6.  
    7. readSocket = new QUdpSocket(this);
    8. readSocket->bind(QHostAddress::LocalHost, 50885);
    9. connect(readSocket, SIGNAL(readyRead()), this, SLOT(readAllValue()));
    10. }
    11.  
    12. MainWindow::~MainWindow()
    13. {
    14. delete ui;
    15. }
    16.  
    17. void MainWindow::readAllValue()
    18. {
    19. QByteArray mReceiveDatagram;
    20.  
    21. do
    22. {
    23. mReceiveDatagram.resize(int(readSocket->pendingDatagramSize()));
    24. readSocket->readDatagram(mReceiveDatagram.data(), mReceiveDatagram.size());
    25. } while(readSocket->hasPendingDatagrams());
    26.  
    27. QDateTime dateTime;
    28. QDataStream stream(&mReceiveDatagram, QIODevice::ReadOnly);
    29. stream.setVersion(QDataStream::Qt_5_9);
    30. stream >> dateTime >> readPacket.myChannel_Nr >> readPacket.AC_Volt >> readPacket.DC_Volt
    31. >> readPacket.AC_Current >> readPacket.DC_Current >> readPacket.Potential;
    32.  
    33. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by malone; 18th January 2019 at 07:09.

  5. #5
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: transfer struct data on udpSocket

    Quote Originally Posted by malone View Post
    i don't have. i only started both programs(SendObject and ReceiveObject). Normally , the class sendObject is for serialization of my struct Object and the class ReceiveObject is for deserialization, i th thought so. Maybe it's my code that was badly written.
    It is always a good idea narrow down a problem by testing different steps separately.

    Serialization/deserialization, for example, can be easily tested with a QBuffer instead of a socket.

    Quote Originally Posted by malone View Post
    i don't receive anything. i tried to sniff my network with wireshark, something is sent that i cannot read or receive on my Class receiveObject.
    Well, then you have to debug why that does not happen before concerning yourself if you possibly also have problems in the deserialization code.

    If there is no data to read, there is no data to deserialize.

    Quote Originally Posted by malone View Post
    i want to send all datagrams, that is the goal of my program. i didn't know that i discard all datagrams except the last
    You have a loop that reads all available datagrams into a single buffer, each loop iteration overwriting the previously read data.
    Thus you end up with only the data of the last datagram.

    Quote Originally Posted by malone View Post
    How to use it?
    By streaming the vector into the stream

    Quote Originally Posted by malone View Post
    i didn't understand what do you mean? normally with my class "sendObject" i want to send 40 object of type struct on the socket.
    The loops use "40" as hard coded value. If the vector is shorter the loop will crash. If the vector is longer, some values won't be sent.

    Iterating over a vector by index usually refers to the vector's size or element count.
    Sending a vector would then also first send that number so that the receiving side know how many elements to expect.

    Quote Originally Posted by malone View Post
    I written a simple program that send only one Object of type struct and receives it. It works fine.
    Good.
    Next step is to see how many bytes get written when you send a full vector of elements and the compare that to the number of bytes received on the other side.

    Separately ensure that serialization and deserialization work as a round trip.

    Cheers,
    _

  6. #6
    Join Date
    Jan 2019
    Posts
    11
    Thanks
    4
    Qt products
    Qt5 Qt/Embedded
    Platforms
    Unix/X11

    Default Re: transfer struct data on udpSocket

    Next step is to see how many bytes get written when you send a full vector of elements and the compare that to the number of bytes received on the other side.
    but the problem is that i don't get sent with QDatagram a full vector of elements. You told me, that when i used a for-loop, i discard all datagrams except the last. Can show me with a simple code example, how i can send a full vector of elements. May be 20 objetc of type struct with 4 elements.
    Thank you!

  7. #7
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: transfer struct data on udpSocket

    You told me, that when i used a for-loop, i discard all datagrams except the last.
    In your first post, in receiveObjects.cpp, the loop starting at line 45 reads one pending datagram each time through the loop, and it stores it into the same datagram instance. This overwrites whatever the previous contents might have been because before reading the datagram, the object gets resized to whatever size is waiting to be read. The result is that the final datagram object only contains the last datagram you read.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  8. The following user says thank you to d_stranz for this useful post:

    malone (22nd January 2019)

Similar Threads

  1. Qt Data transfer
    By Shibby284 in forum Qt Programming
    Replies: 10
    Last Post: 26th July 2015, 05:24
  2. Fastest way to transfer Data over tcp
    By Qiieha in forum General Programming
    Replies: 21
    Last Post: 29th July 2012, 18:11
  3. Data transfer between QIODevice
    By benlau in forum Qt Programming
    Replies: 0
    Last Post: 24th February 2010, 05:59
  4. Transfer Data Between Dialogs
    By umulingu in forum Qt Programming
    Replies: 4
    Last Post: 19th February 2010, 08:35

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.