Russian Qt Forum
Сентябрь 25, 2024, 23:30 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: QDataStream in(tcpSocket), теперь readyRead от tcpSocket идут в in, так?  (Прочитано 5475 раз)
Ruzzz
Гость
« : Август 13, 2009, 00:47 »

Т.е. если я использую QDataStream in(tcpSocket), то in возьмет на себя получение всех частей(чанков)? И мне просто остается пользоватся оператором in >> MY_VAR, но все еще следует проверять перед чтением этим tcpSocket->bytesAvailable(), так ли?

Если так, то могу ли я все это проделать при самом первой посылке readyRead от tcpSocket?
Записан
Ruzzz
Гость
« Ответ #1 : Август 13, 2009, 00:56 »

И еще вопрос по readAll, он дает гарантию что прочитает все за один раз? Или нужно использовать что то типа:
Код
C++ (Qt)
   while(tcpSocket->state() == QAbstractSocket::ConnectedState) {
 
       if (!tcpSocket.waitForReadyRead(timeout)) return;
 
       block = tcpSocket.readAll();
       ...
 
   } // while
Записан
Ruzzz
Гость
« Ответ #2 : Август 13, 2009, 00:59 »

Интересует именно обработка в qt заголовка 'CHUNKED', хотя может и еще какие нюансы есть
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #3 : Август 13, 2009, 08:18 »

Цитировать
И еще вопрос по readAll, он дает гарантию что прочитает все за один раз?
Неа, если глянуть в исходники , то максимум за раз может прочитать <=4096 байт (если не путаю)!

т.е. прочитает ВСЕ что пришло в сокет - но это не значит что это ВСЕ - есть ВСЁ ! Улыбающийся

А обязательно использовать QDataStream ?
« Последнее редактирование: Август 13, 2009, 08:20 от kuzulis » Записан

ArchLinux x86_64 / Win10 64 bit
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #4 : Август 13, 2009, 08:32 »

И я бы например читал вот таким макаром (пример без использования сигнала readyRead):
Код:
...
    QByteArray data;
    bool ret = sock->waitForReadyRead(таймаут ожидания прихода пакета данных в сокет);
    if (ret) {
        do {
            quint64 bav = sock->bytesAvailable();
            if (bav > 0)
                data.append(read(bav));
            else return ошибка;
        } while (sock->waitForReadyRead(таймаут ожидания следующего байта в сокет);) //например около 5-50 мс, в зависимости от твоей идеологии приложения
        return data;
    } else return таймаут
...
Записан

ArchLinux x86_64 / Win10 64 bit
Ruzzz
Гость
« Ответ #5 : Август 13, 2009, 10:23 »

да исходники я изучаю, не всегда получается разобраться в них (
Тогда еще вопрос, почему это «if (bav > 0) … else return ошибка;» — разве это ошибка? Или если sock->waitForReadyRead вернул true, но прочитали 0 байт, значит ошибка?
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #6 : Август 13, 2009, 11:36 »

Цитировать
Тогда еще вопрос, почему это «if (bav > 0) … else return ошибка;» — разве это ошибка? Или если sock->waitForReadyRead вернул true, но прочитали 0 байт, значит ошибка?
в данном случае - ДА! т.к. если ret = true - то это значит что пришел хотябы 1 байт пакета, и если после этого bytesAvailable вернет 0 - то значит это ошибка, т.к. вернуть должно >0
Записан

ArchLinux x86_64 / Win10 64 bit
Ruzzz
Гость
« Ответ #7 : Август 13, 2009, 21:12 »

Неа, если глянуть в исходники , то максимум за раз может прочитать <=4096 байт (если не путаю)!
Похоже что путаете ) Вот из qiodevice.cpp для QByteArray QIODevice::readAll():
Код
C++ (Qt)
   if (d->isSequential() || size() == 0) {
       // Read it in chunks. Use bytesAvailable() as an unreliable hint for
       // sequential devices, but try to read 4K as a minimum.
       int chunkSize = qMax(qint64(4096), bytesAvailable());
       qint64 totalRead = 0;
       forever {
           tmp.resize(tmp.size() + chunkSize);
           qint64 readBytes = read(tmp.data() + totalRead, chunkSize);
           tmp.chop(chunkSize - (readBytes < 0 ? 0 : readBytes));
           if (readBytes <= 0)
               return tmp;
           totalRead += readBytes;
           chunkSize = qMax(qint64(4096), bytesAvailable());
       }

Как видим - пытаемся прочитать минимум 4096, а максимуи сколько дают Улыбающийся Причем в цикле пытаемся и пытаемся читать. И если мы ждем что нам должны что-то прислать, то только какая-либо ошибка может помешать нам считать все пришедшие данные. По-моему так.

Да и как видим если мы используем ReadAll, то перед этим не нужно проверять этим bytesAvailable, просто ReadAll это сделает, хотя все зависит от ситуации. В вот для read возможно стоит также проверить то что возвращает она. Вообще вот:
Код
C++ (Qt)
qint64 QIODevice::bytesAvailable() const
{
   Q_D(const QIODevice);
   if (!d->isSequential())
       return qMax(size() - d->pos, qint64(0));
   return d->buffer.size();
}
То есть bytesAvailable просто возвращает разницу размера и позиции внутреннего буфера. Так что я бы лучше проверял что возвращают функции read
« Последнее редактирование: Август 13, 2009, 21:49 от Ruzzz » Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.114 секунд. Запросов: 22.