@sddvxd

Когда вызывается сигнал «QTcpSocket::readyRead()»?

Здравствуйте! Осваиваю передачу данных по TCP блоками по 4 байта. В первых двух байтах передаю размер блока. Но возникло непонимание - во время вызова сигнала QTcpSocket::readyRead() я ожидаю в количестве входящих байтов увидеть число 6, а приходят все данные. Это сбивает с толку и вызывает недопонимание. Фрагменты клиента и сервера соответственно:

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("");


Прием данных на сервере:

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);
    }

}


Почему в метод slotReadClient поступают сразу все байты? Сервер ждет, пока все байты не поступят к нему и только тогда вызывает сигнал readyRead()?
  • Вопрос задан
  • 612 просмотров
Решения вопроса 1
@sddvxd Автор вопроса
Решил свой вопрос. Просто поставил задержку между записью 2 секунды и начал отладку серверного приложения - сигнал QTcpSocket::readyRead() вызывается только при полном принятии байтов
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
fzfx
@fzfx
18,5 дм
когда и в каком объёме отправлять пакеты TCP - решает сетевой стек операционной системы. вы можете попробовать косвенно повлиять на это, задав в опциях сокета параметр TCP_NODELAY, что, впрочем, также не гарантирует то, что в приходящем массиве будет устраивающий вас объём данных.
если хотите, чтобы во входящем пакете было ровно то количество байт, которое передаёте на отправку - используйте UDP.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы