![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Протокол обмена между клиентом и сервером
Gek1 © (2005-05-18 18:30:00)Имееться ClientSocket, работающий в неблокирующим режиме.
Протокол обмена устроен так, что пакеты уходящие от сервера сжимаются алгоритмом Хаффмана. Каждый пакет имеет разную длинну.
Как известно - по пути пакеты могут резаться и склеиватся. Но получается что расжатый Хаффманом кусок пакета даст совсем другие данные. Практически всегда эти первая часть данных будет не поврежденна, что даст мне понять что за пакет идет и я смогу дождатся пока прийдет его полная длинна.
Но иногда рассжатый кусочек пакета настолько искажается, что мой алгоритм дает збои.
Сам протокол обмена я поменять не могу. Он придуман не мною и очень давно. Сервер тоже написан не мною. Я написал всего лишь клиент для сервера.
Возникает вопрос:
Можно ли всетаки как-то узнать длинну целого пакета, который отправлял сервер?
Мастера, подскажите пожалуйста что можно сделать в данной ситуации?
P.S. если понадобится код - приведу.
Sha (2005-06-08 09:33:00) [1]Интересно было бы посмотреть на то, что получится.
Gek1 (2005-06-07 21:54:00) [2]Digitman © (06.06.05 15:46) [101]
Дерево - константа. Причем как со стороны сервера так и со стороны клиента. См. [38].
> ну ты сам подумай (забудь на секунду про своего хаффмана)
> - можно ли, к примеру, декодировать поток принимаемых шифрованных
> данных, предваряемых ключем шифрования (т.е. ключ передается
> где-то ПЕРЕД собственно данными), если размер ключа заранее
> неизвестен ?
>
> можно ли без отмычки и без лома открыть дверь, если ты получил
> лишь некую часть ключа и даже не знаешь как выглядит целый
> ключ ?
Конечно не совсем так. Отмычка как раз у нас есть (дерево хаффмана). Но мне понятно что ты имеешь виду и этот метод я как раз и пытаюсь полностью определить. И похоже уже получается.
В любом случае спасибо всем ВАМ за помошь мне.
Digitman (2005-06-06 15:46:00) [3]
> Gek1 (06.06.05 15:24) [100]
> а как проверить на целостность дерева?
а я почем знаю ?
протокол-то исследуешь ты, а не я ..
наеврно сам хаффман передает где-то в своемзаголовке эту инфу ..
ну ты сам подумай (забудь на секунду про своего хаффмана) - можно ли, к примеру, декодировать поток принимаемых шифрованных данных, предваряемых ключем шифрования (т.е. ключ передается где-то ПЕРЕД собственно данными), если размер ключа заранее неизвестен ?
можно ли без отмычки и без лома открыть дверь, если ты получил лишь некую часть ключа и даже не знаешь как выглядит целый ключ ?
Gek1 (2005-06-06 15:24:00) [4]Digitman © (06.06.05 15:20) [97]
а как проверить на целостность дерева?
Sha © (06.06.05 15:20) [98]
Да может прийти 3 варианта:
0х4FE9 а потом 0х9A
0х4F а потом 0хE99A
или просто 0х4FE99A
Gek1 (2005-06-06 15:22:00) [5]Это реальный лог ... я веду лог всего что отправляю и что принимаю. Причем эти 2 пакета могут ходить по отдельности и могут вместе. Я привел пример, когда они вместе.
Смотри описание этого пакета:
0x33 Packet
Last Modified on Thursday, 19-Nov-1998
Pause/Resume Client (2 bytes)
· BYTE cmd
· BYTE pause/resume (0=pause, 1=resume)
Digitman (2005-06-06 15:20:00) [6]
> Gek1 (06.06.05 14:57) [95]
ты никак не можешь понять, что для успешной работы Хаффман-декомпрессора нужно на принимающей стороне поиметь сначала целоедерево, сформированное Хаффман-компрессором передающей стороны !
и уж имея целоедерево можно постепенно декомпрессировать поступающие фрагменты собственно сжатых данных..
Sha (2005-06-06 15:20:00) [7]В смысле рельно может придти 0х4FE99A
Sha (2005-06-06 15:18:00) [8]> Gek1 (06.06.05 14:57) [95]
> Вот смотри пример:
> Сервер хочет нам отправить 2 информационных пакета
> (по 2 байта):
> 0х3301 и 0х3300.
> Так как сервер в момент отправки все пакеты соединяет, то
> получится так:
> 0х33013300
Ты реально ловил такие пакеты, или просто предполагаешь,
что они могут такими приходить?
Gek1 (2005-06-06 14:57:00) [9]Sha © (05.06.05 11:32) [94]
Вот смотри пример:
Сервер хочет нам отправить 2 информационных пакета (по 2 байта):
0х3301 и 0х3300.
Так как сервер в момент отправки все пакеты соединяет, то получится так:
0х33013300
Далее Сервер сожмет эту цепочку данных алгоритмом Хаффмана и получатся такие 3 байтика:
0х4FE99A
Далее прием:
Вариант 1:
Получили 0х4FE99A. Распаковали моим способом и там получились 2 пакета: 0х3301 и 0х3300.
(Способ [89] отработает как вариант 2. см. ниже)
Вариант 2:
Данные по дороге к нам порезались и пришли первые 2 байта (0х4FE9). Но мы на клиенте еще не знаем сколько всего должно быть. Расжимаем и получаем 0х3301. Видим что информационный пакет целый и обрабатываем его. Дальше нам приходит еще один байтик: 0х9A
Расжимая его получаем 0х75. Дальше о последствиях понятно.
Если мой алгоритм дает збои только с этими редкими проблемами, то вариант [89] - не заработает никогда.
Этот пример думаю хорошо показывает какие збои могут возникнуть, когда фрагментируються сжатые данные между клиентом и сервером.
Таких вариантов очень много. Предусмотреть все - невозможно. Проблемы возникают в следствии фрагментации сжатых данных.
Кто может подсказать как с этим бороться?
Sha (2005-06-05 11:32:00) [10]> Gek1 (04.06.05 13:43) [93]
> Этот метод бы подошел, если бы Сервер каждый информационный
> пакет данных сжимал и отправлял бы. Но сервер перед отправкой
> сжимает все информационные пакеты и отправляет одним целым
> сжатым пакетом.
Для приведенного тобой перехвата мой метод прекрасно работает.
Приведи перехваченные данные для случая, когда он, по-твоему, работать не должен.
Gek1 (2005-06-04 13:43:00) [11]Sha © (21.05.05 21:32) [89]
Этот метод бы подошел, если бы Сервер каждый информационный пакет данных сжимал и отправлял бы. Но сервер перед отправкой сжимает все информационные пакеты и отправляет одним целым сжатым пакетом.
Defunct © (31.05.05 01:56) [90]
в Случае [81] сервер собирался отправлять пакет 0xA9. Он его сжал и отправил целиком. Хотя мне до сих пор интересно почему сжатый пакет порезался на именно такие 2 кусочка.
Sha © (31.05.05 15:48) [91]
Шапок там не наблюдал. Та всевремя только один информационные пакеты. Причем если была бы шапка, а я пытался ее разбирать как инфорационный пакет, то это дело неработало бы и 5-ти минут.
А так это работает сутками. И иногда (замечено на плохих коннектах) мой алгоритм дает збой.
После долгих анализов обычного клиента заметил такую вешь:
Если игровым персонажем подбежать к домику, в котором много айтимов, то получается следующее:
Сервер начинает собирать всю информацию об айтимах в "пучки" пакетов. Каждый пучок, состоящий в среднем из 100-200 информативных пакетов сервер сжимает и отправляет. Но на клиентской стороне начинают происходит какието задержи в зборе пакетов. Такое ощущение что там в OnRead стоит сразу sleep(1000), а потом только читается принятый буфер и обрабатывается.
Я так решил, потому, что айтимы появлялись через некую задержку, после принятия их от сервера. Будто он с помощью sleep ждал на всякий случай еще каких то даных.
Defunct (2005-06-01 21:36:00) [12]> Sha
Конечно, я же этот протокол не "курил". Просто по логике должно было бы быть так.
Sha (2005-05-31 15:48:00) [13]> Defunct © (31.05.05 01:56) [90]
> Очевидно. Сервер отправляет шапку зашифрованного сообщения коротким пакетом, а дальше данные.
Ты, конечно, понимаешь, что на это полагаться нельзя.
Defunct (2005-05-31 01:56:00) [14]всю ветку было лень читать. и тем более вникать.
Eraser © (20.05.05 15:18) [83]
Digitman © (20.05.05 15:24) [85]
TCP "режет" и "разбивает" большой кусок данных на пакеты.
Но в этом случае с вами согласен, именно в случае [81] ничего не резалось, иначе первый пакет был бы максимального объема, а второй - что осталось.
Gek1 (20.05.05 15:16) [81]
Очевидно. Сервер отправляет шапку зашифрованного сообщения коротким пакетом, а дальше данные.
Sha (2005-05-21 21:32:00) [15]> Gek1 (20.05.05 15:27) [86]
> А что по поводу [84]?
Все необходимые данные у тебя имеются.
Во-первых, надо обязательно внести исправление, указанное Digitman [9].
Во-вторых, переделай DecompressNew в boolean функцию,
возвращающую true, если ей удалось выделить и разжать
из накопленных данных команду/ответ сервера.
Ее надо немного подправить, так чтобы она разжимала
данных не больше длины команды сервера. Это легко сделать,
т.к. после получения первого разжатого байта для команды
фиксированной длины ты можешь определить ее длину
по ее типу, а для команды переменной длины, ты можешь
определить ее длину по следующим двум байтам.
Далее, если DecompressNew вернула true, ты отрабатываешь
разжатую команду сервера и повторяешь вызов DecompressNew
(с новым смещением во входном буфере) и обработку ответа сервера.
Когда DecompressNew вернет false, сдвигаешь данные в входном буфере и ждешь новых данных.
Успехов.
Digitman (2005-05-20 15:32:00) [16]
> А что по поводу [84]?
а по поводу [84] - изучать протокол за тебя никто не намерен. это твои проблемы.
Eraser (2005-05-20 15:29:00) [17]Gek1 (20.05.05 15:21) [84]
На первый взгляд в том листинге, который ты привёл не видно этой стоп последовательности.
Советую пообращать внимание на самые первые 2 или 4 байта сообщения. Это возможно размер блока. Тут проверять надо... у меня к сожалению на это времени нету.
Gek1 (2005-05-20 15:27:00) [18]
> Digitman © (20.05.05 15:24) [85]
Пошел я внимательно еще раз читать книжку.
А что по поводу [84]?
Digitman (2005-05-20 15:24:00) [19]
> ТСП протокол порезал
ТСП протокол вообще ничего не "режет"
Gek1 (2005-05-20 15:21:00) [20]А теперь вопрос:
Где может передаваться длина или стоп последовательность в [81]?
Стоит тронуть там один байтик, и результат будет нарушен и неверен.
Вот поэтому я решил, что в сжатом блоке данных информации о их длинне нету. Может у вас получится обнаружить эту информацию.