简体   繁体   中英

Qt QIODevice::write / QTcpSocket::write and bytes written

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM