S
S
sddvxd2018-09-10 01:53:24
Qt
sddvxd, 2018-09-10 01:53:24

When is the "QTcpSocket::readyRead()" signal called?

Hello! I am mastering data transfer over TCP in blocks of 4 bytes. In the first two bytes I pass the block size. But there was a misunderstanding - during the call of the QTcpSocket::readyRead() signal, I expect to see the number 6 in the number of incoming bytes, and all the data comes. This is confusing and misunderstood. Fragments of the client and server, respectively:

QByteArray arrBlock;

    QDataStream bufferOut(&arrBlock, QIODevice::WriteOnly);
    bufferOut.setVersion(QDataStream::Qt_5_3);
    bufferOut << pLineEdit->text(); // Записываю в бинарный стрим данные с текстового поля

    int lenData = arrBlock.size();
    int nBlockSize = 4;
    for(int j = 0; lenData > j && lenData >= nBlockSize; j += nBlockSize){

        for(int i = 0; i < sizeof(quint16); i++)
            arrBlock.insert(0, 0x01); // Заполняю начало массива двумя байтами

        bufferOut.device()->seek(0); //Смещаю указатель потока на начало для записи числа байтов в блоке

        bufferOut << quint16(nBlockSize); // Записываю размер блока

        pSocket->write(arrBlock, nBlockSize + sizeof (quint16)); // Беру 6 байт из массива байт и отправляю на сервер
        arrBlock.remove(0, nBlockSize + sizeof(quint16)); // Удаляю первые 6 байт, поскольку они уже не нужны
    }

    if(lenData % nBlockSize != 0 && lenData){ // Если остался кусок меньше 4 байт
        for(int i = 0; i < sizeof(quint16); i++)
            arrBlock.insert(0, 0x01);

        bufferOut.device()->seek(0);
        bufferOut << quint16(lenData);
        pSocket->write(arrBlock, lenData + sizeof (quint16));
    }
    pLineEdit->setText("");

Receiving data on the server:
void Server::slotReadClient(){
    QTcpSocket* pSocket = (QTcpSocket*)sender();
    QDataStream in(pSocket);
    in.setVersion(QDataStream::Qt_5_3);
    int debug = pSocket->bytesAvailable(); //Больше 6!
    for(;;){
        if(!nNextBlockSize){
            if(pSocket->bytesAvailable() < sizeof(quint16)){
                return;
            }
            in >> nNextBlockSize;
        }
        if(pSocket->bytesAvailable() < nNextBlockSize){
            return;
        }
        QString str;

        in >> str;

        QString strMessage = str;
        pTextEdit->append(strMessage);
        nNextBlockSize = 0;

        sendToClients(pSocket->peerAddress().toString() + " написал: " + str);
    }

}

Why does the slotReadClient method receive all the bytes at once? Does the server wait until all the bytes have arrived and only then call the readyRead() signal?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
S
sddvxd, 2018-09-10
@sddvxd

Resolved my issue. I just set a delay between writes of 2 seconds and started debugging the server application - the QTcpSocket::readyRead() signal is called only when the bytes are fully received

V
vreitech, 2018-09-10
@fzfx

when and in what volume to send TCP packets - decides the network stack of the operating system. you can try to indirectly influence this by setting the TCP_NODELAY parameter in the socket options, which, however, also does not guarantee that the amount of data that suits you will be in the incoming array.
if you want the incoming packet to have exactly the number of bytes that you transfer to send, use UDP.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question