c++xmlqtudpqudpsocket

Send XML data by UDP


I am writing a program that on input sends out a message with some data. I want to be able to send out a udp message by multicast, and I want to be able to send this message out in an xml format. Currently my program is written in qt, and if possible I would like to keep it in qt.

From the documentation, I can create and send data with a udp socket by the following:

udpSocket = new QUdpSocket(this);
QByteArray datagram = "stuff here";
udpSocket->writeDatagram(datagram.data(), datagram.size(), groupAddress, port)

where the groupaddress is the ip address I am sending the message to, and the port is the port that I am sending it on.

on the other hand, I can use:

QXmlStreamWriter xml;
xml.setDevice(QIODevice);

to send out xml data, and the QIODevice can be either sending data to a file, or sending data out by TCP, and formatting all the data in xml form.

However, I am unable to find a way to set the udpSocket as the device for QXmlStreamWriter and set to to automatically send out that data when it is passed this way. Is there a way to do this? Or am I going to have to format everything in a byte array in order to send it out?

Edit: In case someone else stumbles across this looking for information. The method described by Nejat (Listed as the answer) will indeed send xml data by UDP. However, QXmlStreamWriter ends up sending a very large number of packets, which is not very useful if you are trying to send a single formatted xml block. If you need to send a formatted xml block, then you will want to do the following:

Step 1: create your udp socket

udpSocket = new QUdpSocket(this);

Step 2: create a QByteArray, and set it as the "device" that QXmlStreamWriter is writing into.

QByteArray message;
QXmlStreamWriter xml(&message);
//proceed to write the xml like you would normally

Step 3: send your QByteArray message like the documentation states.

udpSocket->writeDatagram(message.data(), message.size(), groupAddress, port);

Doing it this way will create a single, large packet, then send that packet via UDP messages. It is up to you to make sure that your packet is small enough that it won't be broken up by the routing on its way to its destination.


Solution

  • QUdpSocket inherits from QAbstractSocket which also inherits from QIODevice. So you can pass your QUdpSocket to the QXmlStreamWriter constructor. This will allow you to write to the device through the stream.

    From the documentation about QUdpSocket :

    If you want to use the standard QIODevice functions read(), readLine(), write(), etc., you must first connect the socket directly to a peer by calling connectToHost().

    So you should first connect to a peer :

    udpSocket = new QUdpSocket(this);
    udpSocket->connectToHost(ip, port);
    udpSocket->waitForConnected(1000);
    QXmlStreamWriter xml(udpSocket);
    
    xml.setAutoFormatting(true);
    xml.writeStartDocument();
    ...
    xml.writeStartElement("bookmark");
    xml.writeTextElement("title", "Some Text");
    xml.writeEndElement();
    ...
    xml.writeEndDocument();