why QByteArray returned from QTcpSocket::readAll() is initialized only with NULL bytes
-
I write a network queue with socket and have a problem.
Look at the line marked as a problem. I get the
data
array in the slot connected to the signaldataReady
. All time the size of the array is equal to response size (expected size) fromsend
method. It's okay. But first two arrays (replies) works correct and other arrays (third or more) contain only NULL bytes and it is not okay. I cannot get why.In the debugger it looks like this:
Name | Value | Type data | | QByteArray |---[0] | 0 '\0' | char |---[1] | 0 '\0' | char ... |---[N] | 0 '\0' | char
I am sure a server replies correct because I used WireShark to see what data really comes by network (I saw TCP data segment and it looks like what I want to get. It is not filled with null bytes at least).
Code example:
/* * header file */ class AsyncSocket { public: void send(const QByteArray &msg, int responseSize); bool busy() const; signals: void dataReady(const QByteArray &data); private slots: void readyRead(); private: QTcpSocket *socket; }; /* * Source file */ void AsyncSocket::send(const QByteArray &msg, int responseSize) { socket->setReadBufferSize(responseSize); socket->write(msg, msg.size()); socket->flush(); } /* * I use buffer size both busy flag and size of expected message * If the size is 0 the socket is free. */ bool AsyncSocket::busy() const { return socket->readBufferSize(); } void AsyncSocket::readyRead() { if (socket->bytesAvailable() == socket->readBufferSize()) { emit (dataReady(socket->readAll())); // <----- HERE IS PROBLEM socket->setReadBufferSize(0); } }
I skipped some implementation not related to receiving/parameters_checking to simplify the code above.
Any idea why
QTcpSocket::readAll()
can return NULL filled byte array? -
I don't understand what you're trying to achieve with the readBufferSize, esp. not the busy() function... Also we don't see where you're sending the data - maybe you send null bytes there...
-
Hi, just guessing but the signal you emit
void dataReady(const QByteArray &data);
takes only a reference to the QByteArray from socket->readAll() and if the socket is deleted before you've copied the QByteArray then that could explain why you see only null bytes.
You could try changing the the signal tovoid dataReady(QByteArray data);
-
@hskoglund said in why QByteArray returned from QTcpSocket::readAll() is initialized only with NULL bytes:
takes only a reference to the QByteArray from socket->readAll() and if the socket is deleted before you've copied the QByteArray then that could explain why you see only null bytes.
That can't happen, and if it does then it's a bug in the user code - (directly) deleting an object in its slot handler is not allowed.
@bduminyuk,
just drop thereadBufferSize
calls all around, they do nothing for you. -
@Christian-Ehrlicher, I try to achieve following points with the
readBufferSize
:- set expected message size
- control socket states like: free (buffer size is NULL), busy (buffer size is not NULL) and readyForReading (buffer is full, it emits signal itself)
- avoid redundant class members (like
bool busyFlag; int maxSize;
)
@kshegunov, I found a mistake related with sizes of messages if I limit max size with
readBufferSize
. If the size of comming message is not equal to the expected size thereadAll
(by the way theread
also) method returns QByteArray initialized like QByteArray(expectedSize, '\0');In my case I waited 3.76 Kb of data but the server sended 3.9 Kb. I have no reasons why but I got byte array like I showed above. So, I changed the size and fixed the problem. Thank you for your answers.
-
You're going about it the wrong way. The
readBufferSize
property controls the internal (read) buffer of theQTcpSocket
. You don't need to touch it at all. Just read whatever is you want to read directly from the socket. If you want to make your life easier you can also make use ofQDataStream
and its transactions (assuming you're talking to a Qt application on the other side).PS.
control socket states like: free (buffer size is NULL), busy (buffer size is not NULL) and readyForReading (buffer is full, it emits signal itself)
This makes no sense at all. Qt will asynchronously populate the socket object's buffer, so it's never "busy" or "free".