problem with QLocalSocket sending continues data to QLocalServer
-
Christian Ehrlicher Lifetime Qt Championreplied to Venkateswaran on last edited by Christian Ehrlicher
@Venkateswaran Why? It's a stream with no further protocol. It can even happen that you get a readyRead signal for every single byte you sent.
-
@Venkateswaran
And it absolutely is not! :)readyRead
fires when there is at least 1 byte available.readAll
reads all that happens to be there when it is called. Anything ranging from 0 bytes to every byte sent!readyRead
won't fire again till you've done areadAll
.
That's it. No one-to-one. Your job to buffer received data at receiver, or split it up, if that's what you want to do.
-
@JonB Thanks for clarifying this. Now I have another problem, on the server-side, I need to call another function with received test string from the client. I have tested the readAll() and as you said I'm receiving 130 bytes all at once (which is 5 times my test string). So how do I separate on server-side? I'm using QDataStream on client-side to send data and is there an elegant way to decouple the received bytes at server-side with QDataStream? maybe its a really basic question but it would be helpful for me if you show some example.
-
@Venkateswaran
Start by: have you read (and understood!) all the detail in https://doc.qt.io/qt-5/qdatastream.html#details ? And do look at subsection https://doc.qt.io/qt-5/qdatastream.html#using-read-transactions, because you may be looking for that.How is the client sending? ("I'm using QDataStream on client-side to send data" --- with just which calls on what data object types?) If you are using
QDataStream
at client send you will wantQDataStream
at server receive. And just btw: when you talk sometimes about "bytes" and sometimes about "string" do you indeed wantQDataStream
or did you maybe wantQTextStream
? -
@Venkateswaran
Nope :) Not unless you want to, it just stops client proceeding to the next line of code till bytes are written. But it makes no difference to the protocol/behaviour. And no effect at server-side. -
@JonB Thanks for the information. I want to send Boolean, Number, String from the client so DataStream would be the right one.
This is how I'm sending data from the client :void TestClient::sendDataToServer() { QByteArray block; QDataStream out(&block, QIODevice::WriteOnly); out.setVersion(QDataStream::Qt_5_10); QString testString = "test data"; out << quint32(testString.size()); out << testString; m_socket->write(block); m_socket->flush(); }
This is what I tried at the server side to receive data (and it work for this basic example).
void TestServer::onNewData() { QLocalSocket* client = qobject_cast<QLocalSocket*>(sender()); qCritical() << "TestServer::onNewData" << client->bytesAvailable(); QDataStream in; in.setDevice(client); in.setVersion(QDataStream::Qt_5_10); quint32 blockSize = 0; QString test; while(client->bytesAvailable() > (int)sizeof(quint32)) { in >> blockSize; if (client->bytesAvailable() < blockSize || in.atEnd()) return; in >> test; qDebug() << test << "printing received value"; } qCritical() << "data read by server"; }
But looks like This Answer has a nice example to start with
-
@Venkateswaran
Note that the link you reference (by @VRonin) uses the transactions I suggested earlier: https://doc.qt.io/qt-5/qdatastream.html#using-read-transactions. NobytesAvailable()
or buffering. Up to you. -
@JonB said in problem with QLocalSocket sending continues data to QLocalServer:
readyRead won't fire again till you've done a readAll.
This is not correct. From https://doc.qt.io/qt-5/qabstractsocket.html
The
readyRead()
signal is emitted every time a new chunk of data has arrived.So it doesn't care whether you read the data or not
I suggest having a look at this article it uses
QTcpSocket
but the code is exactly the same forQLocalSocket
. I'd focus on theChatClient::onReadyRead
method and its explanation below -
@VRonin said in problem with QLocalSocket sending continues data to QLocalServer:
This is not correct.
Damn, and sorry! I thought that it had said that, but not. I may have confused with
readyRead() is not emitted recursively; if you reenter the event loop or call waitForReadyRead() inside a slot connected to the readyRead() signal, the signal will not be reemitted (although waitForReadyRead() may still return true).