We are quite confused about the behavior of QIODevice::write
in general and the QTcpSocket
implementation specifically. There is a similar question already, but the answer is not really satisfactory. The main confusion stems from the there mentioned bytesWritten
signal respectively the waitForBytesWritten
method. Those two seem to indicate the bytes that were written from the buffer employed by the QIODevice
to the actual underlying device (there must be such buffer, otherwise the method would not make much sense). The question then is though, if the number returned by QIODevice::write
corresponds with this number, or if in that case it indicates the number of bytes that were stored in the internal buffer , not the bytes written to the underlying device . If the number returned would indicate the bytes written to the internal buffer, we would need to employ a pattern like the following to ensure all our data is written:
void writeAll(QIODevice& device, const QByteArray& data) {
int written = 0;
do {
written = device.write(data.constData() + written, data.size() - written);
} while(written < data.size());
}
However, this will insert duplicate data if the return value of QIODevice::write
corresponds with the meaning of the bytesWritten
signal. The documentation is very confusing about this, as in both methods the word device is used, even though it seems logical and the general understanding, that one actually indicates written to buffer, and not device.
So to summarize, the question is: Is the number returned bye QIODevice::write
the number of bytes written to the underlying device, and hence its save to call QIODevice::write
without checking the returned number of bytes, as everything is stored in the internal buffer. Or does it indicate how much bytes it could store internally and a pattern like the above writeAll
has to be employed to safely write all data to the device?
(UPDATE: Looking at the source, the QTcpSocket::write
implementation actually will never return less bytes than one wanted to write, so the writeAll
above is not needed. However, that is specific to the socket and this Qt version, the documentation is still confusing...)
QTcpSocket
is a buffered QAbstractSocket
. An internal buffer is allocated inside QAbstractSocket
, and data is copied in that buffer. The return value of write is the size of the data passed to write()
.
waitForBytesWritten
waits until the data in the internal buffer of QAbstractSocket
is written to the native socket.
That previous question answers your question, as does the QIODevice::write(const char * data, qint64 maxSize)
documentation:
Writes at most maxSize bytes of data from data to the device. Returns the number of bytes that were actually written, or -1 if an error occurred.
This can (and will in real life) return less than what you requested, and it's up to you to call write
again with the remainder.
As for waitForBytesWritten
:
For buffered devices , this function waits until a payload of buffered written data has been written to the device...
It applies only to buffered devices. Not all devices are buffered. If they are, and you wrote less than what the buffer can hold, write
can return successfully before the device has finished sending all the data.
Devices are not necessarily buffered.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.