Unsolved Listening and receiving data from a socket.
-
@SPlatten
While you're waiting for someone who understands better than I....You are reading data into a
QByteArray
in a transaction. But the sender has not sent aQByteArray
(has it?). So what do you expect to happen?EDIT Mine crossed with @Christian-Ehrlicher's. Let me try to hint briefly. To use
<<
, and transactions, the client must be sendingQDataStream
objects for you to receive them. Your client is not, it's just sending a stream of bytes.That means, all you can do is read whatever bytes happen to be there when
readyRead
is raised. And that could be anything from the whole string down to just 1 byte. As it stands --- without inventing some protocol for properly sending messages --- all you can do is keep accumulating received bytes until the final}
arrives. Push bytes received into a member buffer. Exit thereadyRead
handler and allow it to be called again for further bytes. Append future bytes to the pending buffer. When it contains a}
you have received the complete client "message".If the client were a Qt program, and it was using
QDataStream
to send aQByteArray
for the message, then you could usesocket >> QByteArray
and a transaction. When bytes arrived the transaction would look to see whether the wholeQByteArray
was there. If not all bytes arrived yet, it would buffer those arrived andcommitTransaction()
returnsfalse
. When more bytes arrive, it would try appending them. When the whole array received,commitTransaction()
will returntrue
. -
@Christian-Ehrlicher , this is just test data on the URL to see that something is being received.
-
@JonB , how the data is received is nothing to do with how it is sent, I can receive the same data as either a QString or array, the content is the same. I've also tested the same code using a QString, the result is the same.
What I mean by this is that receiving data in a QByteArray or QString makes no difference, the content would be the same, the only difference is the way 0 (nulls) are handled.
-
@SPlatten
You are failing to understand. Nothing to do withQByteArray
vsQString
.how the data is received is nothing to do with how it is sent
Not at all true, given that you are using
QByteArray
, and transactions. How it is sent totally does matter. Nothing other than client sending aQByteArray
via aQDataStream
will satisfy your server receiver code. You are thinking, somehow, that bytes sent withoutQDataStream
can be received asQDataStream
, which they can't.I have typed in a detailed explanation in an EDIT to my previous to try to help you. Until you understand that you are going to struggle, I urge you to read it carefully.... :)
-
@JonB , It was my understanding which is obviously wrong that I could receive any data on the socket using a QDataStream, in my testing I'm trying to receive data from a browser which is a standard HTTP request.
I'm now replacing the QDataStream receive data with:
void clsListener::onDataIn() { QByteArray arybytMsg; while( mpClient->bytesAvailable() ) { QByteArray arybytMsg = mpClient->readAll(); qdbg() << "HERE"; } }
Just to see if that resolves the issue.
[Edit] This now works and I am receiving the data.
-
@SPlatten said in Listening and receiving data from a socket.:
It was my understanding which is obviously wrong
It's all in the docs: "A data stream is a binary stream of encoded information..."
It really helps (as already told you many times) to read the documentation of a class before using it. -
@Christian-Ehrlicher , thank you, that just takes time which I don't feel I have.
-
@SPlatten said in Listening and receiving data from a socket.:
that just takes time which I don't feel I have.
You would have solved the issue by yourself 17hours ago when you would have read the documentation.
-
@SPlatten
This is getting better, but you are still assuming that onereadyRead
call toonDataIn
allows you to write a loop onbytesAvailable()
and that will accumulate all bytes sent. It won't. It may do because your message data is so small, but not necessarily, and not if the data gets larger. (Try sending a very long [e.g. many K? megabytes?] string!)I showed you the only correct algorithm. Save the data received into a persistent (e.g. member variable) buffer. Append to that as more arrives. Check if you have now received the terminating
}
from your sending "protocol". When you do, you have the complete message. Period. -
@SPlatten said in Listening and receiving data from a socket.:
how the data is received is nothing to do with how it is sent, I can receive the same data as either a QString or array, the content is the same. I've also tested the same code using a QString, the result is the same.
That's not true, you have to read data in the same way you sent them when you are using
QDataStream
.
As TCP is a stream socket, you can not be sure all data have been received, sostartTransaction()
in combination withcommitTransaction()
will simply reception side. When not all data are received,QDataStream
will rollback the readed data and so you can retry reading on next received data chunk.But to ensure this works, you have to read what you have transfered, in the same order.
-
@SPlatten said in Listening and receiving data from a socket.:
that just takes time which I don't feel I have
But you have time to ask in a forum and wait for an answer?!
-
@jsulm , whilst I try to resolve it myself, granted I could also be reading the documentation.