![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Протокол обмена между клиентом и сервером
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]
сервер не его
попал человек