Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

UDP data + circular buffer



  • Hey there !
    I would like to receive UDP data and then put them in a circular buffer. I'm on it since monday and I dont know how to code it .... I dont found an example where both of the circular buffer and UDP reception exists... Actually I did a source code socket but that's all
    Do you have like an example or something ? :)
    Thanks !


  • Lifetime Qt Champion

    @Chanchan What exactly are your problems?
    Did you read https://doc.qt.io/qt-5/qudpsocket.html?
    There are links to examples as well.



  • @jsulm I already did an UDP socket, here is my code :

    #include "myudp.h"
    
    MyUDP::MyUDP(QObject *parent) :
        QObject(parent)
    {
        // create a QUDP socket
        socket = new QUdpSocket(this);
    
    
        // The most common way to use QUdpSocket class is
        // to bind to an address and port using bind()
        // bool QAbstractSocket::bind(const QHostAddress & address,
        //     quint16 port = 0, BindMode mode = DefaultForPlatform)
        socket->bind(QHostAddress("192.168.2.x"), 14500);
    
        connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead()));
    }
    
    void MyUDP::HelloUDP()
    {
        QByteArray Data;
        Data.append("En ecoute");
    
        // Sends the datagram datagram
        // to the host address and at port.
        // qint64 QUdpSocket::writeDatagram(const QByteArray & datagram,
        //                      const QHostAddress & host, quint16 port)
        socket->writeDatagram(Data, QHostAddress("192.168.2.x"), 14500);
    }
    
    void MyUDP::readyRead()
    {
        // when data comes in
        const auto SIZE_BUF = 500000; 
        QByteArray buffer;
        buffer.reserve(SIZE_BUF);
        buffer.resize(socket->pendingDatagramSize());
    
        QHostAddress sender;
        quint16 senderPort;
    
        // qint64 QUdpSocket::readDatagram(char * data, qint64 maxSize,
        //                 QHostAddress * address = 0, quint16 * port = 0)
        // Receives a datagram no larger than maxSize bytes and stores it in data.
        // The sender's host address and port is stored in *address and *port
        // (unless the pointers are 0).
    
        socket->readDatagram(buffer.data(), buffer.size(),&sender, &senderPort);
    
        qDebug() << "Message from: " << sender.toString();
        qDebug() << "Message port: " << senderPort;
        qDebug() << "Message: " << buffer;
    }
    
    
    

    But instead of use a "classic" buffer, I would integrate a Circular Buffer.
    How Should I do that ?


  • Lifetime Qt Champion

    @Chanchan You will need to implement the circular buffer by yourself or find existing one. As far as I know Qt does not have such a container.


  • Moderators

    @jsulm actually, I quick google search resulted in this surprise class

    https://doc.qt.io/archives/qt-5.5/qt3d-qcircularbuffer.html#details

    it's part of qt3d, which would explain, why I haven't heard of it before.


  • Lifetime Qt Champion

    @J.Hilk Yes, I saw it.
    But I'm not sure why it is part of Qt3D module?! And is it still there in recent versions?



  • @J.Hilk
    Yes I saw this page, I tried to implement it to my example but I didn't succeed :/


  • Moderators

    @jsulm said in UDP data + circular buffer:

    And is it still there in recent versions

    that's a god point, I can't find it in the 5.12 docs. Therefore I don't think so ?

    Anyway a basic circular buff is like 40 lines. One should be able to do create on fairly easily with based on e.g. QVector.



  • Ok, I will try found it and integrate to my code
    I have another problem but I prefer to open another thread for it ^^
    Thank you :)



  • Ring buffers are only applicable in specialized situations where you need a container of constant memory footprint and quick deque access of elements (such as hardware device I/O. I can see such a thing being in the 3d graphics modules, but its utility in the general framework is very limited. The buffering of incoming UDP is such a case where its utility is valid. There are many online references describing how to implement the ring buffer container.

    EDIT: a gotcha that the op needs to be aware of is that you CANNOT create a ring buffer of n characters and expect to access sequences of those characters. each element must be explicitly accessed as a single operation. The reason is that when the head/tail loops back to element n[0] the sequence of characters is no longer contiguous.


  • Lifetime Qt Champion

    @Chanchan and @J-Hilk: I might be wrong, but isn't QQueue exactly what you want?


  • Lifetime Qt Champion

    @jsulm said in UDP data + circular buffer:

    @Chanchan You will need to implement the circular buffer by yourself or find existing one. As far as I know Qt does not have such a container.

    As said above, there is QQueue.


  • Moderators

    @aha_1980 It's probably a better starting point, but the QQueue is not limited in size -> No circular buffer, right?


  • Lifetime Qt Champion

    @J.Hilk said in UDP data + circular buffer:

    QQueue is not limited in size

    Correct. If you need this behavior, you have to check size() before enqueue().



  • Actually my case is :
    I receive a lot of UDP data, I have to implement a process function to transfert these data to the good function, this function will implement datas, etc...
    For this I need a circular buffer, I will take a look on your tips, thank you :)


Log in to reply