Название: Клиент не успевает обрабатывать данные (слабый канал или железо) Отправлено: Ground от Июль 31, 2011, 15:24 Добрый день!
Сегодня тестировал клиент-сервер: с ноутбуком (клиент) отошел достаточно далеко от роутера - клиент повис, загрузив при этом весь процессор. В ходе непродолжительного дебага выяснилось, что клиент не успевает обработать все данные, первая партия приходит на обработку - 100 байт, за это время прилетает 200 байт, потом 400 и.т.д. Аналогичная ситуация на слабом железе, но тут все понятнее. Вопрос по первому явлению, почему так? Из-за слабого канала скачет скорость передачи, за какой-то промежуток времени прилетает сразу много байт - и клиент виснет, правильно я понимаю? И второй вопрос - как такое явление можно подавить или хотя бы минимизировать его влияние, ведь должны же быть какие-то стандартные приемы? Немного про сервер: с сервера клиентам отсылается стабильным потоком 2КБ/с. Причем, если накапливаются 2 партии по 2КБ, то первая партия уже не нужна. Код отправки: Код
Код получения: Код
Вот на втором цикле при приемке данных и зависает программа. Чуть не забыл! Отдельно хотелось бы спросить про первый цикл при приеме данных (увидел данную идею у М. Шлее), насколько он корректен и нужен ли вообще? Сам ставлю его под сомнение. Название: Re: Клиент не успевает обрабатывать данные (слабый канал или железо) Отправлено: LisandreL от Июль 31, 2011, 16:06 В читателе:
1) Код Заменить на просто: Код: data.append(clientSocket->readAll()); 2) Первый if можно в while внести инвертировав условие ( просто для красоты ). 3) Где оно у вас на втором цикле виснет? В любом случае data должен рано или поздно кончиться. Название: Re: Клиент не успевает обрабатывать данные (слабый канал или железо) Отправлено: Ground от Август 01, 2011, 09:34 Код Заменить на просто: Код: data.append(clientSocket->readAll()); Спасибо за наводку. Такую элементарную вещь выпустил из головы. Проблема была в том, что при каждом вызове Client::slotReadyRead() переменная data, хранящая принятые данные, создавалась заново. В результате, пока соединение работает стабильно - от сервера приходит по одной целой группе данных за раз. Как только соединение становится хуже - количество принятых за раз байт прыгает, в результате байты парсятся с ошибками и вызывают segmentation fault. Решил проблему, сделав data статической. Но тогда встает ребром другая проблема. Наблюдал следующую ситуацию: сервер отправляет данные клиенту, клиент кое-как их принимает, но в один прекрасный момент соединение на секунду прерывается. После этого обрыва сервер все так же отправляет данные клиенту (без write error), но клиент ничего не принимает и думает, что сервер просто ничего не отсылает. Через несколько минут на стороне сервера появляется ошибка write error, соединение разрывается. Клиент теряет связь с сервером примерно где-то в этом же промежутке времени. Какими методами можно справиться с такой проблемой? Т.е. либо переподключать клиента (но не через 2 минуты, а побыстрее), либо как-то возобновлять текущее соединение? Пока что в мыслях два варианта - отправка подтверждения доставки данных, и второе - широковещательный запрос или что-то в этом духе. Может быть есть какие-нибудь другие способы, а если нет - какой из этих лучше? Название: Re: Клиент не успевает обрабатывать данные (слабый канал или железо) Отправлено: kuzulis от Август 01, 2011, 11:33 ТС, почитай ка уже теорию: про модель ISO/OSI + возьми и посмотри для примера спецификацию на какой-нить протокол передачи данных (например X-Modem - как один из самых простых), а потом уже приступай к реализации своего велосипеда.
PS: Замучали уже с этими вопросами. Понаделают хрени, а потом спрашивают почему не работает... Название: Re: Клиент не успевает обрабатывать данные (слабый канал или железо) Отправлено: Ground от Август 01, 2011, 12:08 ТС, почитай ка уже теорию: про модель ISO/OSI + возьми и посмотри для примера спецификацию на какой-нить протокол передачи данных (например X-Modem - как один из самых простых), а потом уже приступай к реализации своего велосипеда. PS: Замучали уже с этими вопросами. Понаделают хрени, а потом спрашивают почему не работает... Так ведь в том-то и проблема - откуда мы (велосипедостроители) знаем что читать? В обычных книжках такого не пишут, в примерах Qt - тоже такого не найдешь. Только в узкоспециализированной литературе, но опять же вопрос - какой? Ей богу, никто ж не просит отвечать на вопрос, но можно хотя бы написать - rtfm x-modem и iso/osi, даже за это огромное спасибо. И замечу, все с чего-то начинали |