Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: предотвращение повторной передачи большого блока данных  (Прочитано 13082 раз)
0 Пользователей и 2 Гостей смотрят эту тему.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« : 30-12-2007 13:14 » 

стоит следующая задача:
имеется абстрактные сервер и клиент. Клиент подключается по TCP к серверу и скачивает блок данных (описание внутрипрограммых объектов), скажем , 1 Мб . Связь - медленная, скачивание может растянуться на минуты. Связь также нестабильна и может часто рваться. Клиент использует пинг для определения разрыва, если обнаружен разрыв - клиент подцепляется заново автоматически и СНОВА скачивает блок данных.
Блок данных, возможно , остался неизменным на сервере (а клиент его не изменяет) , так вот вопрос:

какие данные небольшого размера клиент может сообщить серверу , чтобы сервер определил, что данные , скачанные клиентом до этого, всё ещё идентичны с данными на сервере (при этом, соответственно, повторного скачивания не требуется - клиент может использовать предыдущий скачанный блок данных) ? Достоверность определения желательна 100%
Записан

sss
Специалист

ru
Offline Offline

« Ответ #1 : 30-12-2007 14:07 » 

Алексей1153++, например как в Active Directory. Там используется порядковый номер обновления объекта, ну или можно назвать его номером версии. Если управляет хранилищем объектов только один сервер, этого достаточно.
Записан

while (8==8)
Scorp__)
Молодой специалист

ru
Offline Offline
Пол: Мужской

« Ответ #2 : 30-12-2007 14:15 » 

Алексей1153++, это докачкой называется Улыбаюсь
К сожалению, быстрым поиском никакого кода не нашел. Постараюсь описать возможную логику.

Для файла на сервере заранее подсчитывается хеш. Файл на сервере бьется на мелкие блоки, эти блоки нумеруются. Когда клиент скачивает очередной блок, он отправляет серверу подтверждение, что блок с таким-то номером он скачал, тогда сервер инкрементирует номер блока в текущей закачке у себя. На запрос клиента о продолжении закачки, выдает ему следующий блок. По окончании закачки клиент проверяет хеш файла, и сверяет его с тем, что хранится на сервере. Ну и если неправильно, то перекачиваем. В торрентах, как я понимаю, используется хитрая хеш функция, которая позволяет вычислить в каких блоках была ошибка (для этого сами блоки тоже хешируются). Ну или проверять по хешу каждый блок и в случае ошибки тут же его перекачивать.

В общем посмотри опенсорсные торрент клиенты или downloader-ы. Правда, я боюсь что прям код выдернуть оттуда у тебя не получится. В общем главное - это грамотно размер блоков выставить. 1 Мб - слишком много. 

В результате обратного траффика у тебя всего ничего, номер блока и хэш, в один килобайтный TCP пакет влезет.
« Последнее редактирование: 30-12-2007 14:17 от Scorp__) » Записан

- А Вы сами-то верите в привидения?
- Конечно, нет, - ответил лектор и медленно растаял в воздухе.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #3 : 30-12-2007 15:44 » 

sss, нумерация - а что , мысль Улыбаюсь Так , наверное , и сделаю

Scorp__), с докачкой, наверное не получится - изначально не было под это заточено, а переделывать сейчас долго и глюков исправлять потом наверняка (а как иначе Отлично ) это мне не позволят сейчас. На будущее буду иметь в виду.

некая сложность в том, что данные сервер вытаскивает из базы (оч-много параметров) и собирает в текстовом виде файлик , потом файл сжимается (это быстро происходит) и передаётся (а это долго). А вот с нумерацией , согласен, красиво получается (и переделывать минимум) - после сборки файла сверяемся, с предыдущей версией файла, если разные - увеличиваем счётчик на сервере и передаём файл. А если файл такой же, да и клиент прислал счётчик, равный текущему на сервере - то не отправляем заново
Записан

sss
Специалист

ru
Offline Offline

« Ответ #4 : 30-12-2007 16:29 » 

Алексей1153++, да передает номер версии и имеющийся объем. Сервер отвечает, например, да докачивай остаток, или, нет давай заново или все ок, версия не изменилась.
Записан

while (8==8)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #5 : 31-12-2007 09:36 » 

объём не поможет - данные могут смениться в любом месте , не только размер данных. Другое дело, если бы можно было на блоки побить , но это в данный момент тоже невозможно - где нибудь в середине длина строки поменялась у какого нибудь объекта - и всё , приехали. Остаётся только номер версии. __int64 подойдёт Отлично
Записан

Mayor
Специалист

ru
Offline Offline

« Ответ #6 : 31-01-2008 12:53 » new

c хешами не парься, их имеет смысл исползовать, только в случае подозрения на фальсификацию части файла в распределенной серверной среде

просто перед скачкой запоминай клиентом серверное время изменения\создания файла, если перед докачкой оно прежнее делай откат на 3к для параноиков или просто указывай серваку перемещение на место обрыва в файле

Записан

1n c0de we trust
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #7 : 31-01-2008 14:46 » 

Mayor1, не, слишком сложно ) Да и не передаю я частями - только целый файл. Мне проще проверить, что он уже отсылался
Записан

Mayor
Специалист

ru
Offline Offline

« Ответ #8 : 03-02-2008 14:29 » 

Mayor1, не, слишком сложно ) Да и не передаю я частями - только целый файл. Мне проще проверить, что он уже отсылался

тогда гипотетически, в случае обрыва связи, клиенту в первую очередь следует передать серверу, версию блока данные для закачки, далее:

1 в случае когда новой версии данные нет, об этом сообщается клиенту и он передает точку останова

2 в случае когда скачиваемая версия удалена сервером, клиент должен удалить оставшуюся часть и начать закачку поновой

3 если есть более новая версия, то тебе прежде всего следует решить, кто будет принимать решение о докачке клиент или сервер ...

как другой вариант в случае таймстемпа, сервер допустим обязан хранить все недокаченные блоки в течении определенного интервала времени:

тогда клиент попросту по сверке времени определяет есть ли блок на сервере, после чего запрашивает докачку или иницирует запрос нового блока

тебе главное не забить сервер блоками отвалившихся навсегда клиентов и в случае докачки уникальным образом идентифицировать блок передаваемой информации

Записан

1n c0de we trust
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #9 : 03-02-2008 15:10 » 

Mayor1, нет, ты не правильно представил себе, что у меня имеется на сервере и клиенте: на сервере лежит описание кучи объектов, это описание может меняться и дополняться. Когда подключается клиент, он скачивает себе текущую версию данных. При любом изменении описания на сервере, клиенту сообщается об этом и он скачивает новую версию. Если клиент оторвался, то, подключившись взад, он скачивает описание (но если оно не поменялось - скачивать не надо, использовать уже ранее скаченное) Никакого забивания нету Улыбаюсь Понятий "докаченные" или "недокаченные" блоки тут нету. Есть только весь целый блок
Записан

Mayor
Специалист

ru
Offline Offline

« Ответ #10 : 04-02-2008 16:39 » 

тогда тебе ни таймстемпа ни версии блока не нада, просто создаешь много потоковый клиент или пользуешься select

если соединение оборвалось, запрашиваешь клиентом докачку с места обрыва

одновременно ждешь клиентом события обновления блока, при его получении обрываешь закачку и начинаешь скачивать поновой

как вариант, если можешь выделить обновления блока, ползуешься патчем на клиенте - но с этим имхо возни будет очень много
Записан

1n c0de we trust
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #11 : 04-02-2008 18:30 » 

Mayor1, да я говорю, проблема уже решена Улыбаюсь
Ну а проблем с обрывом блока и не было - на временнОй диаграмме это можно выразить так:
Код:
0с                              30с          10мин      11мин 
|вкл. клиента и закачка данных |  работа       | разрыв  |  соединение| закачка данных .....
Записан

Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines