3

In the fortuneserver sample of Qt, a QString is sent by the method sendFortune(). Therefore one QString is selected from the QStringList fortunes:

QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_0);
out << (quint16)0;
out << fortunes.at(qrand() % fortunes.size());
out.device()->seek(0);
out << (quint16)(block.size() - sizeof(quint16));

QTcpSocket *clientConnection = tcpServer->nextPendingConnection();
clientConnection->write(block);

Is it also possible to send another type of data, like files, images or multiple strings? Or is it just possible to send a single string?

My second question: What is the advantage of sending data as QByteArry and why do I have to define (quint16) by setting up the QDataStream?

admdrew
  • 3,600
  • 4
  • 22
  • 39
3ef9g
  • 661
  • 1
  • 8
  • 16
  • To be very simple, client/server communication uses protocols like TCP. This protocol encapsulate your message to reach your destination. Messages are bytes. Bytes could be images, strings, file, whatever, because everything is bytes. About the quint16 question, you have to understand that you need to define your rules to send/receive a message, otherwise you'll never know when a message starts and when it ends. – Martin Oct 01 '14 at 17:16
  • Are there any examples out there? Because that's the fact - I would like to understand it - but without some exercises, it's hard to understand. ... Which size should I use for strings, which size for images or text files ... I have no idea ... Some help would be great – 3ef9g Oct 05 '14 at 13:03
  • You don't have to worry about these sizes. Have in mind that tcp comm is a stream communication. So you receive 0101101010101... when ever in time. You have to define your rules (or use some application protocols such as http) to know the beginning and the end of the message. Let's say you want to send a string "hello". You first write 0x00 0x00 to know it's the beginning of a message. Then you write hello. And then you write the size of your string 0x05. So you send 00 00 68 65 6c 6c 6f 00 05 on your socket. – Martin Oct 06 '14 at 08:56
  • On the other side, you'll receive 00 00 68 65 6c 6c 6f 00 05. You first take the 2 last bytes 00 05, compute that you expect a 5 bytes lenght message. So you read from the 3rd byte because the first two ones are 00 00, and you have 68 65 6c 6c 6f. It's a message with a length of 5 so it's a valid message. So you have your "hello" string. Why such a complicate thing for that ? Because with tcp, you communicate with paquets, and you don't know how many paquets you need to transmit your data and obviously, if you well receive all your paquets. – Martin Oct 06 '14 at 09:01

2 Answers2

3

You don't send the data as QDataStream, QDataStream is a class that impersonates a stream, a way to transfer data, like wire. QByteArray represents a storage for your data. So, you can send data as QByteArray. You can try QTcpSocket's member function called "int write(QByteArray)", like in the example you provided. Just take the image, the file, any other data and convert it to QByteArray. Here is where you will need QDataStream. Bind the stream to bytearray like this.

QByteArray dat; QDataStream out(&dat, QIODevice::WriteOnly);

and use out to fill dat.

out << myImage << myImage2;

When you had finished filling the QByteArray, send it:

mySocket.write(dat);

don't forget to check the return value. Read the docs and you will succeed.

Asalle
  • 931
  • 16
  • 38
0

To know if you have read all the data send by the other side of the socket, I use the commitTransaction() function from QDataStream:

Client::Client()
{
    ....
    connect(tcpSocket, &QIODevice::readyRead, this, &Client::readData);
    ....
}

void Client::readData()
{
    in.startTransaction();

    QString data;
    in >> data;

    if (!in.commitTransaction())
    {
        qDebug() << TAG << "incomplete: " << data;
        // readyRead will be called again when there is more data
        return;
    }

    // data is complete, do something with it
    ....
Boy
  • 5,006
  • 4
  • 47
  • 60