QTcpSocket : readRead() not being triggered when data is written on the socket
-
Sure,
Ask yourself where do you think you are actually writing the data to the client socket?
QDataStream::QDataStream(QIODevice *d)
You are just writing to some QByteArray, you want to call the constructor which asks for a ptr to QIODevice i.e. your client socket.
You actually did the QDataStream right on the client side.Also I would use readyRead signal from the socket rather than use a thread's run method.
-
Don't use a blocking connection when waiting for data but signals and slots.
Then your QIODevice::seek() does not work: https://doc.qt.io/qt-5/qiodevice.html#details -
Hi,
One thing you did not share was the code reading the data received.
Why are you using the blocking API and then mixing in the synchronous API ?
-
Hi, so I'm fairly new to both QT and Tcp programming so perhaps the way I'm seeing things is completely wrong.
Basically, the idea is that the client will receive data packets at a very fast rate from the server that it needs to update live on a graph. So I thought that I would have the receive function in a separate thread. This is what happens: whenever the client sends the request to start the data streaming, it spawns a new thread that receives the data and then emits a SIGNAL for the client to process it and display the results. However, inside the newly created thread, I had to waitForReadyRead otherwise I don't know if data is available on the socket...
Feel free to suggest another way to do this as it might not be the best way to do it...
-
@RBLL
BecauseQTcpSocket
is already implemented asynchronously for you, you don't need the overhead or complication of your own separate threads or signals. And no need to call the unattractivewaitForReadyRead
.Dump your separate thread. Just use signal https://doc.qt.io/qt-5/qiodevice.html#readyRead from your GUI thread to act on data received.
-
@RBLL
Yep, give it a go. Hopefully it keeps up, come back if it is does not, that's a separate issue.I also see you seem to be receiving "messages" back to your client.
readyRead
signal will activate (potentially) even with just one byte back, it makes no guarantee the number of bytes you'll get in one go will be equal to a complete sent message. Your client code is responsible for buffering received data to implement this. To save you writing it, look at https://doc.qt.io/qt-5/qiodevice.html#startTransaction, where Qt has the code to implement this for you.I think the example https://doc.qt.io/qt-5/qtnetwork-fortuneclient-example.html uses transactions, it's worth looking at.
-
@JonB
Ah thats a fair point. I always assumed that at least the number of bytes would make it. I'll look into transactions!However, I still have the issue (even after removing the client thread and only usind readyRead) that the readyRead signal is only triggered once. I'll keep investigating. The issue might be from the server. I'll keep you posted.
Thank you very much for you help!
-
@RBLL said in QTcpSocket : readRead() not being triggered when data is written on the socket:
that the readyRead signal is only triggered once
Again (although it may well be your code, leave you to investigate), just as
readyRead
might fire with just the first byte of a "message", it might also fire just once with hundreds of bytes across multiple messages if multiple messages are sent (while developing/debugging, seebytesAvailable
fromreadyRead
). That's why transactions can help you. You will need to play and see how it behaves in your environment.EDIT P.S. Also, ISTR
readyRead
will not fire again until you have done something likereadAll
to read the available bytes from the (internal) buffer.