Answer the question
In order to leave comments, you need to log in
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("");
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);
}
}
Answer the question
In order to leave comments, you need to log in
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
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 questionAsk a Question
731 491 924 answers to any question