![]() |
|
![]() ![]() ![]() |
|
ecspertiza |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 763 Регистрация: 3.11.2008 Где: г.Смоленск Репутация: 4 Всего: 5 |
Возможно ли используя QHttp ограничить скорость закачки как это делает DownloadMaster или любые торрент клиенты?
|
|||
|
||||
SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 81 Всего: 91 |
Управлять скоростью скачивания можно ограничивая в размерах буффер сокета и чтением из него настолько часто насколько быстрей ты хочешь что-то скачать. Если буффер полностью заполняется, то чтение данных из сокета прекращается до того момента пока в буффере не появится место, при этом данные, которые отправляет удаленный сокет никуда не деваются, он просто их не отправляет до того момента, пока скачивающий ему не скажет продолжить.
Для QHttp это можно сделать через int QHttp::setSocket ( QTcpSocket * socket ) но надо предварительно создать сокет и вызвать void QAbstractSocket::setReadBufferSize ( qint64 size ). Но я рекомендую перевести приложение на QNetworkAccessManager, т.к. в Qt 4.6 класс QHttp будет deprecated. Уже сейчас тролли не принимают багрепорты на этот класс. А для QNAM достаточно вызвать void QNetworkReply::setReadBufferSize ( qint64 size ) [virtual], который возвратится от QNetworkReply * QNetworkAccessManager::get ( const QNetworkRequest & request ) Но еще раз повторюсь. Чтобы замедлить скачивание надо игнорить сигнал readyRead так часто как тебе нужно, а значит тебе придется проверять сколько времени прошло с момента последнего чтения данных. Т.е. если тебе нужно ограничить скорость до 500кб/с, то тут у тебя 2 варианта. Ты можешь выставить размер буффера в 500кб и проверять прошла ли секунда перед следующим чтением или ты можешь влиять через время, установить размер буффера в 50 байт и читать их каждые 100 мс. |
|||
|
||||
ecspertiza |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 763 Регистрация: 3.11.2008 Где: г.Смоленск Репутация: 4 Всего: 5 |
Спасибо доходчего объяснил
![]() |
|||
|
||||
ecspertiza |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 763 Регистрация: 3.11.2008 Где: г.Смоленск Репутация: 4 Всего: 5 |
SABROG, можешь глянуть правильно ли я тебя понял я накидал небольшой примерчик
![]() Где я мог недодумать?
|
|||
|
||||
SABROG |
|
||||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 81 Всего: 91 |
Ты бы хоть объяснил, что этот код делает, а то я ничего не понял
![]() Тут утечка у тебя похоже, указатель на QFile не удаляется:
Да и код по меньшей мере странный. У тебя этот метод вызывается так часто насколько большой размер у файла и насколько маленький буффер. При быстрых скоростях это утопия, если надо записать скажем 50 байт в файл, открытие и закрытие файла, постоянно файловые операции. Насчет очереди не понятно - QList<QNetworkReply *> currentDownload; Вроде запрашивается всего один Url, а для чего целый список, как у тебя может прийти скажем десяток replyFinished? Да и по логике получается, что в один и тот же файл записываются данные с каждого запроса в этом списке. Этот код мне тоже не совсем понятен. Через метод size() идет попытка определить есть ли доступные данные для считывания и если нет, то мы зачем-то обрубаем всё нафиг, типа тормозишь сервак или провайдер ну и х. с тобой, не буду я докачивать ничего, даже если ты ответишь мне через 20 секунд.
Метод replyComplite (почему не complete?). removeAll можно заменить на removeOne(reply), сомневаюсь, что там может быть несколько идентичных указателей, а выйгрыш в скорости будет, т.к. проход по массиву закончится при первом совпадении. Вообще идея с таймером странная какая-то. Может быть запускать таймер в слоте на сигнал readyRead, который прочитает нужные нам данные из буффера с некоторой паузой? Насчет утечек памяти, попробуй использовать IBM Rational Purify, чтобы найти места, где утекает память. |
||||
|
|||||
ecspertiza |
|
||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 763 Регистрация: 3.11.2008 Где: г.Смоленск Репутация: 4 Всего: 5 |
Извеняюсь торопился ![]() насчёт записи в файл согласен затупил.
Я хочу сделать закачку в несколько потоков, и думал что QList<QNetworkReply *> мне в этом поможет, ан нет это просто очередь ![]() Мне нужно сделать многопоточную закачку с ограниченой скоростью, но вот когда я в отдельном потоке создаю QNetworkAccessManager софтина начинает ругаться вот так
собственно вот код
|
||||||
|
|||||||
SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 81 Всего: 91 |
![]() Я бы посоветовал посмотреть в сторону QtConcurrent вместо QThread, и использовать QFuture для сборки файла из многопоточной закачки. Это сообщение отредактировал(а) SABROG - 22.6.2009, 16:42 |
|||
|
||||
ecspertiza |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 763 Регистрация: 3.11.2008 Где: г.Смоленск Репутация: 4 Всего: 5 |
У меня такое ощущение что QNetworkAccessManager может работать только в главном потоке, я накидал пример в котором создаётся поток и внём я пытаюсь получить http заголовок чтобы определить размер файла, всё замечательно никаких ошибок но и заголовки при этом не передаются
![]() Присоединённый файл ( Кол-во скачиваний: 6 ) ![]() |
|||
|
||||
ecspertiza |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 763 Регистрация: 3.11.2008 Где: г.Смоленск Репутация: 4 Всего: 5 |
всё разобрался прошу прощения за панику
![]() SABROG, отдельное спасибо оченно помог. |
|||
|
||||
ecspertiza |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 763 Регистрация: 3.11.2008 Где: г.Смоленск Репутация: 4 Всего: 5 |
Что то я совсем запутолся, есть софтина у неё есть класс закачки, он должен отправить заголовок получить размер файла и создать нужное количество потоков для скачивания кусками, если я в потоке задаю размер буффера то софтина жудко жрёт память, если не задаю вылетает.
она в аттаче. не исключаю возможность кривых рук, ткните носом где косячу, а то два дня ковыряюсь и всё не в ту сторону. мда забыл сказать сервер локальный, поэтому скорость скачивания довольнотоки высокая. Да и файл размеров 2Гб. И вообще QNetwork* нерадует, стандартный example download, на этих компанентах тоже жрёт память, при скачивании большого файла тоже вылетает. Что это? Косяк разработчика? Это сообщение отредактировал(а) ecspertiza - 25.6.2009, 11:52 Присоединённый файл ( Кол-во скачиваний: 7 ) ![]() |
|||
|
||||
SABROG |
|
||||||||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 81 Всего: 91 |
![]()
У тебя тут заккоментировано:
И я не нашел метода, который бы писал в файл на сигнал readyRead. Ты пишешь в файл здесь:
В документации сказано, если ты не ловишь событие readyRead, то файл выкачается полностью. Потому наверно и память жрется. Я расскомментировал setReadBufferSize и все-равно не понял почему выкачивание не останавливается при полном заполнении буффера.
Если 10 потоков по 10 мегабайт в буффере, то прога должна кушать около 100Мб оперативки, а жрет 800 мегов и потом падает. Это сообщение отредактировал(а) SABROG - 25.6.2009, 13:39 |
||||||||
|
|||||||||
ecspertiza |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 763 Регистрация: 3.11.2008 Где: г.Смоленск Репутация: 4 Всего: 5 |
Забавно у меня пока такого небыло
![]() |
|||
|
||||
ecspertiza |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 763 Регистрация: 3.11.2008 Где: г.Смоленск Репутация: 4 Всего: 5 |
Ошибка возникает при чтении из QNetworkReply вот в этом месте
Причём если всё это делать не в потоке то всё нормально и память освобождается после reply->readAll() и закачка идёт нормально, а если в потоке то читает некоторое время а потом отваливается, може из за того что QNetworkReply создаётся не в потоке, но переместить его туда методом moveToThread тоже не получается возникает ошибка сигментирования, вообщем я совсем запутолся. |
|||
|
||||
SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 81 Всего: 91 |
||||
|
||||
ecspertiza |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 763 Регистрация: 3.11.2008 Где: г.Смоленск Репутация: 4 Всего: 5 |
ну это я просто привёл кусок кода как в проге в случае с file->write(reply->readAll()) всё тоже самое.
|
|||
|
||||
![]() ![]() ![]() |
Правила форума "С/С++: Кроссплатформенное программирование, QT/Gtk+/wxWidgets" | |
|
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, Любитель. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |