Мы весьма озадачены поведением QIODevice::write
в целом и реализацией QTcpSocket
в частности.Уже есть подобный вопрос , но ответ на самом деле не является удовлетворительным.Основная путаница связана с упомянутым сигналом bytesWritten
и, соответственно, waitForBytesWritten
.Эти два, кажется, указывают байты, которые были записаны из буфера, используемого QIODevice
, на фактическое базовое устройство (такой буфер должен быть, в противном случае метод не будет иметь большого смысла).Тогда возникает вопрос, соответствует ли число, возвращаемое QIODevice::write
этому числу, или если в этом случае оно указывает количество байтов, которые были сохранены во внутреннем буфере ,не байты, записанные на базовое устройство .Если возвращаемое число будет указывать байты, записанные во внутренний буфер, нам нужно будет использовать шаблон, подобный следующему, чтобы гарантировать, что все наши данные записаны:
void writeAll(QIODevice& device, const QByteArray& data) {
int written = 0;
do {
written = device.write(data.constData() + written, data.size() - written);
} while(written < data.size());
}
Однако при этом будут вставлены повторяющиеся данные, есливозвращаемое значение QIODevice::write
соответствует значению сигнала bytesWritten
.Документация очень запутанная по этому поводу, так как в обоих методах используется слово device , даже если это кажется логичным и общее понимание, что на самом деле указывается запись в буфер, а не в device.
Итак, подведем итог: вопрос в том, вернулось ли число пока QIODevice::write
количество байтов, записанных на базовое устройство, и, следовательно, его сохранение для вызова QIODevice::write
без проверки возвращенного количества байтов, так как все хранится во внутреннем буфере.Или это указывает, сколько байтов он может хранить внутри, и шаблон, подобный приведенному выше, writeAll
должен использоваться для безопасной записи всех данных на устройство?
(ОБНОВЛЕНИЕ: Глядя на источник, * 1031Реализация на самом деле никогда не вернет меньше байтов, чем один хотел написать, поэтому приведенное выше writeAll
не требуется. Однако, это специфично для сокета и этой версии Qt, документация по-прежнему сбивает с толку ...)