Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Протокол обмена между клиентом и сервером


Страницы:   1 2 3 4 5 6

Gek1 ©   (2005-05-18 18:30:00) 

Имееться ClientSocket, работающий в неблокирующим режиме.
Протокол обмена устроен так, что пакеты уходящие от сервера сжимаются алгоритмом Хаффмана. Каждый пакет имеет разную длинну.

Как известно - по пути пакеты могут резаться и склеиватся. Но получается что расжатый Хаффманом кусок пакета даст совсем другие данные. Практически всегда эти первая часть данных будет не поврежденна, что даст мне понять что за пакет идет и я смогу дождатся пока прийдет его полная длинна.

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

Сам протокол обмена я поменять не могу. Он придуман не мною и очень давно. Сервер тоже написан не мною. Я написал всего лишь клиент для сервера.

Возникает вопрос:
Можно ли всетаки как-то узнать длинну целого пакета, который отправлял сервер?

Мастера, подскажите пожалуйста что можно сделать в данной ситуации?

P.S. если понадобится код - приведу.


Digitman   (2005-05-19 18:38:00) [61]


> Размер буфферов 50к и 150к.


значения от фонаря, надо понимать ...


Gek1   (2005-05-19 18:22:00) [62]


> ведь это выходной буфер декомпрессора !
> ты же где-то память под него размером выделяешь ?


Как и fIncomingBuf - создаю в OnConnect
освобождаю в OnDisconnect
при этом тамже сбрасываю их длинны на ноль.

Размер буфферов 50к и 150к.


Digitman   (2005-05-19 18:18:00) [63]


> Gek1   (19.05.05 18:07) [40]


ты не понял.
я спросил, где и как у тебя инициализируется значение указательной переменной PHuffDecompress, которое ты передаешь в ф-цию DecompressNew ?

DecompressNew(fIncomingBuf, PHuffDecompress,PHuffDecompressLen,fIncomingBufLen);

ведь это выходной буфер декомпрессора !
ты же где-то память под него размером выделяешь ?

в твоем коде формирование значения PHuffDecompressLen я вижу, но нигде не вижу чтобы ты выделял память под буфер соотв.размера и записывал его адрес в переменную PHuffDecompress перед тем как передать ее параметром в ф-цию декомпрессии


Gek1   (2005-05-19 18:07:00) [64]

pOutArray := pOutData;

Далее в коде уже:
pOutArray^[despos] := -treepos;


Digitman   (2005-05-19 17:51:00) [65]

где и как инициализируется значение PHuffDecompress, передаваемое тобой параметром pOutData ?


Gek1   (2005-05-19 17:36:00) [66]


Procedure DecompressNew(pInData, pOutData : Pointer; var iOut : Integer; iLen : Integer );
var mask : Word;
   bitnum : Byte;
   treepos : SHORT;
   despos, value : Integer;
   pIn : Word;
   pInArray, pOutArray : PArray;
const
tree : array [0..511] of Word =
(
       $0001, $0002, $0003, $0004, $0005, $0000, $0006, $0007,
       $0008, $0009, $000A, $000B, $000C, $000D, $FF00, $000E,
       $000F, $0010, $0011, $0012, $0013, $0014, $0015, $0016,
       $FFFF, $0017, $0018, $0019, $001A, $001B, $001C, $001D,
       $001E, $001F, $0020, $0021, $0022, $0023, $0024, $0025,
       $0026, $0027, $0028, $FFC0, $0029, $002A, $002B, $002C,
       $FFFA, $002D, $002E, $002F, $0030, $0031, $0032, $0033,
       $FF89, $0034, $FFE0, $0035, $0036, $FFF2, $0037, $FFFB,
       $0038, $0039, $003A, $003B, $003C, $FFFE, $003D, $003E,
       $003F, $0040, $0041, $0042, $0043, $0044, $0045, $0046,
       $0047, $0048, $FFCD, $0049, $004A, $004B, $004C, $004D,
       $FF9B, $FF91, $FFFC, $FF9F, $004E, $004F, $FF92, $0050,
       $0051, $FF8C, $0052, $0053, $0054, $FF01, $0055, $0056,
       $0057, $0058, $0059, $005A, $FFF1, $FFF6, $005B, $005C,
       $FFEB, $005D, $FF8B, $005E, $005F, $0060, $0061, $0062,
       $0063, $0064, $FF8E, $0065, $FF97, $0066, $FFE6, $0067,
       $0068, $0069, $006A, $006B, $006C, $006D, $006E, $006F,
       $0070, $FFFD, $0071, $FFF9, $0072, $FF7D, $0073, $FF70,
       $0074, $0075, $FFEC, $0076, $0077, $0078, $0079, $007A,
       $007B, $007C, $007D, $007E, $007F, $0080, $0081, $FF9C,
       $0082, $FFF8, $0083, $0084, $0085, $0086, $FF88, $0087,
       $0088, $FFE1, $0089, $008A, $FF93, $FF16, $008B, $008C,
       $008D, $008E, $008F, $0090, $FF90, $0091, $FFED, $0092,
       $0093, $0094, $0095, $FFBE, $0096, $FF6F, $FFF3, $FFBF,
       $0097, $0098, $0099, $009A, $FFE2, $009B, $009C, $009D,
       $FF9D, $009E, $009F, $00A0, $00A1, $00A2, $FFE9, $00A3,
       $FFE3, $00A4, $FFF5, $00A5, $00A6, $FF8D, $00A7, $00A8,
       $00A9, $00AA, $FFF0, $00AB, $FFDE, $00AC, $00AD, $FF7C,
       $00AE, $FF94, $00AF, $FFEA, $00B0, $FFF7, $00B1, $FFAC,
       $FFEF, $FFDB, $FFE4, $00B2, $00B3, $00B4, $00B5, $00B6,
       $00B7, $00B8, $00B9, $00BA, $00BB, $FF98, $00BC, $FFB2,
       $00BD, $FFC3, $FFB1, $FF4E, $FFC5, $FF7A, $00BE, $FFE7,
       $FFAD, $FFEE, $00BF, $FFC7, $FFBD, $00C0, $FF9E, $00C1,
       $FFF4, $FFBC, $00C2, $00C3, $FFC9, $FF80, $FFE8, $FFCE,
       $FFBA, $00C4, $FFA2, $FFDF, $00C5, $FF7F, $FFB6, $00C6,
       $FFAE, $00C7, $FFC8, $FFA9, $FFD4, $00C8, $FF08, $00C9,
       $FF5D, $FFAF, $FFCC, $FF85, $00CA, $FF8F, $FFD0, $FFD7,
       $FF86, $FFD8, $00CB, $FFA6, $FFCA, $00CC, $FFAA, $FF40,
       $00CD, $00CE, $00CF, $FF7E, $FFCB, $00D0, $FF7B, $FFD3,
       $00D1, $00D2, $00D3, $FFA5, $00D4, $00D5, $FF96, $FFA8,
       $00D6, $00D7, $00D8, $00D9, $00DA, $FFCF, $00DB, $00DC,
       $00DD, $00DE, $00DF, $00E0, $00E1, $00E2, $00E3, $FF9A,
       $FF60, $00E4, $FFD2, $00E5, $FF81, $00E6, $FF99, $00E7,
       $00E8, $00E9, $FFC4, $00EA, $00EB, $FFB4, $00EC, $FF87,
       $00ED, $FFB7, $FF6B, $00EE, $00EF, $FF95, $FFDD, $00F0,
       $FFB9, $FFE5, $FFBB, $00F1, $FFA7, $FFB3, $FFC2, $FF8A,
       $FFB5, $FFAB, $FFB8, $FFC6, $FFC1, $FFB0, $00F2, $FFD6,
       $FF6A, $FF63, $FF75, $FF14, $FF82, $FF0D, $FF72, $FF2A,
       $FF76, $FF32, $FF10, $FF6E, $FF34, $FF6D, $FF68, $FF37,
       $FF1D, $FF31, $FF66, $FF2F, $FF67, $FF02, $FF50, $FF64,
       $FF5B, $FF2E, $FF54, $FF47, $FF3D, $FF56, $FF18, $FF2D,
       $FF25, $FF11, $FF38, $FF4F, $FF51, $FF2C, $FF0C, $FF71,
       $FF0A, $FF55, $FF35, $FF23, $FF36, $FF4B, $FF53, $FF06,
       $FF48, $FF5C, $FF3F, $FF26, $FF39, $FF24, $FF42, $FF07,
       $FF1A, $FF27, $FF57, $FF28, $FF41, $FF3B, $FFD1, $00F3,
       $00F4, $00F5, $00F6, $00F7, $FF6C, $FF61, $00F8, $00F9,
       $FFA4, $FFA3, $FFA0, $FF1F, $FF69, $FFA1, $00FA, $00FB,
       $FF0F, $00FC, $FF5F, $FFDC, $00FD, $00FE, $FF79, $FFD9,
       $FF45, $FF84, $00FF, $FF05, $FF5E, $FF12, $FF0E, $FFDA,
       $FFD5, $FF83, $FF29, $FF03, $FF74, $FF30, $FF77, $FF15,
       $FF62, $FF13, $FF78, $FF33, $FF65, $FF73, $FF1C, $FF1B,
       $FF2B, $FF58, $FF20, $FF3E, $FF3C, $FF1E, $FF49, $FF17,
       $FF19, $FF59, $FF52, $FF43, $FF04, $FF5A, $FF3A, $FF22,
       $FF44, $FF4D, $FF21, $FF4A, $FF4C, $FF46, $FF0B, $FF09
);

begin
bitnum := 8;
treepos := 0;
despos := 0;
pIn := 0;
pInArray := pInData;
pOutArray := pOutData;
value := 0;
mask := 0;
while true do
begin

if (bitnum = 8) then
begin
if (iLen = 0) then
   begin
   iOut := despos;
   Exit;
   end;
iLen := iLen - 1;
value := Byte(pInArray^[pIn]);
pIn := pIn + 1;
bitnum := 0;
mask := $80;
end;

if (value and mask) = mask then treepos := tree[treepos*2]
else treepos := tree[treepos*2+1];

mask := mask SHR 1;
bitnum := bitnum + 1;

if (treepos <= 0) then
begin
if (treepos = -256) then
   begin
   bitnum := 8;
   treepos := 0;
   continue;
   end;
if (despos = iOut) then Exit;
pOutArray^[despos] := -treepos;
despos := despos + 1;
treepos := 0;
end;

end;
end;


Digitman   (2005-05-19 17:31:00) [67]

что за процедура DecompressNew() ?

код можешь привести ?


Gek1   (2005-05-19 17:21:00) [68]

Про MD5 спасибо, что подметил.

Но к сожалению у меня не выходит другое и все силы направленны на решение этой проблемы.


Digitman   (2005-05-19 16:30:00) [69]


> я тестирую на сервере, где fEncryptMetod = 2. Поэтому это
> кусок все время пропускается


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


Digitman   (2005-05-19 16:28:00) [70]

для работы MD5 требуется как минимум условие кратности четырем значения fIncomingBufLen

где ты это условие выполняешь ? нигде.


Gek1   (2005-05-19 16:24:00) [71]


> при fEncryptMetod = 4 до разжатия у тебя и дело может не
> дойти

Это для других сервером. В моем случае я тестирую на сервере, где fEncryptMetod = 2. Поэтому это кусок все время пропускается.


Digitman   (2005-05-19 16:20:00) [72]


> Проверял и пытался определить возможную длинну сжатом пакете


при fEncryptMetod = 4 до разжатия у тебя и дело может не дойти

пытаясь декодировать произвольный шматок принятых данных, ты нарушаешь принципы, заложенные в http://www.faqs.org/rfcs/rfc1321.html


Gek1   (2005-05-19 16:16:00) [73]


> Sha ©   (19.05.05 15:53) [30]

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


Sha   (2005-05-19 15:53:00) [74]

> Сам протокол закрыт и его алгоритм был разгадан кодерами.
> Сами кодеры похоже тоже сталкивались с такой проблемой.

Тут противоречие.


Gek1   (2005-05-19 15:45:00) [75]


> Digitman ©   (19.05.05 15:09) [27]

Проверял и пытался определить возможную длинну сжатом пакете.
Ни вначале ни в конце признаков не заметил.
Если все же судить, что в сжатом пакете должна присутствовать гдето длинна - тогда кто мне обьяснит как распакованный пакет с длинной вместе дает мне практически всегда правильные данные?


> Еще возможен такой вариант: сервер вставляет в поток данных
> спецсимволы сброса, которые сбрасывают алгоритм компрессии/декомпрессии
> в исходное состояние.
> Это своеобразный признак конца/начала пакета.
> В общем, имеет смысл детально разобраться с алгоритмом сжатия.

С дерева таблицы хаффмана данные только читаются. Не записываются. Да и вообще дерево - константа.


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

В том то и дело, что клиент, написанный разработчиками работает отлично.

Сам протокол закрыт и его алгоритм был разгадан кодерами. Сами кодеры похоже тоже сталкивались с такой проблемой. Проблема ясна (выше описана), но алгоритм как ее обойти неизвестен. Я считаю что все же есть гдето какаято изюминка. Может особенность хаффмана или еще чего либо.
Определить так мне и не удалось, поэтому спрашиваю у вас. Может у вас будет решение этой проблеммы.


Sha   (2005-05-19 15:13:00) [76]

Еще возможен такой вариант: сервер вставляет в поток данных спецсимволы сброса, которые сбрасывают алгоритм компрессии/декомпрессии в исходное состояние.
Это своеобразный признак конца/начала пакета.
В общем, имеет смысл детально разобраться с алгоритмом сжатия.

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


Digitman   (2005-05-19 15:09:00) [77]


> Gek1   (19.05.05 14:55) [25]
>
> > Digitman ©   (19.05.05 14:49) [24]
>
> Сжатый порезаный кусок распаковываю


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

тебе же Alexander Panov ©   (19.05.05 14:45) [22] правильно говорит - прикладной протокол долженпредусматривать передачу инф-ции о размере сжатых данных в несжатом виде, например, в 4-х байтах предшествующих "упаковке" ... зная это ты принимаешь сначала (хоть одним куском хоть четырьмя) эти самые 4 байта, берешь из них размер "упаковки" и далее ожидаешь/считываешь "куски" собственно "упаковки", "склеивая" их друг за другом в порядке поступления, до тех пор пока полный размер склеенных тобой "кусков" не будет точно равен тому значению, что ты получил из ранее принятых тех самых 4-х байт ... вот только ПОСЛЕ этого ты можешь смело передать склеенную тобой "упаковку" на дальнейшую обработку, как то "разжатие", "декодирование" и т.д. и т.п.

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


Gek1   (2005-05-19 14:55:00) [78]


> Digitman ©   (19.05.05 14:49) [24]

Сжатый порезаный кусок распаковываю и молусь, чтобы первые байт небыли испорченны. Бо по первому байту я определяю ID пакета, а если его длинна динамическая, то второй и третий байт - длинна. Но это все работает, когда данные не коверкаются при распаковке.


Маркони   (2005-05-19 14:55:00) [79]

пакт порвался предпложим на два куска да так удачно что ... первые два пакета в запаковом виде в первой части а вторые во второй... получили кусок первый... распокавали весь из заголовка пакетов (а это первый байт пакета) получаем ага длинна 7 байт а унас там их 9 распаковалось смотрим по начало + 7 ага длинна пакета должна быть 2 байта ... то бишь нам теперь кажется... что мол мы приняли всё одним таким куском и следующий кусок будем уже воспринимать не как часть предудущего а как новый в резульатте распаковки получим мусор....  так как lzk получения правильной информация надо соединитье го было с предыдущем и распаковать весь.... вот такая хрень


Polevi   (2005-05-19 14:49:00) [80]

>Alexander Panov ©   (19.05.05 14:45) [22]
сервер не его
попал человек


Страницы:   1 2 3 4 5 6

Наверх

Титульная страница Поиск, карта сайта Написать письмо