Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2006.01.29;
Скачать: [xml.tar.bz2];

Вниз

Проблема с TClientSocket. "Непонятные" явления.   Найти похожие ветки 

 
Bazi   (2005-10-20 13:33) [0]

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

Код следующий:


type TArray = array[0..159999] of byte; PArray = ^TArray;

.......

procedure TTestClass.ClientSocketOnRead(Sender: TObject; Socket: TCustomWinSocket);
var i,c,index,reslen : Integer;
   SHex : String;
   Len : Integer;
begin

{ fTempIncBuf : PArray;
 fTempIncBufLen : Integer; }

{Принимаем данные в TempIncBuf}
fTempIncBufLen := 0;
while Socket.ReceiveLength > 0 do
begin
reslen := Socket.ReceiveLength;
index := fTempIncBufLen;
i := 0;
try
i := Socket.ReceiveBuf(&fTempIncBuf^[index], reslen);
except
AddToLog("Error with receiving Some Data");
end;
if (i <= 0) then
   begin
   {в Буфере чтото было, но забрать не получилось}
   AddToLog("Error receiving ReceiveBuf");
   Exit;
   end;
if (i < reslen) then AddToLog("Receiving not full ReceiveBuf");
fTempIncBufLen := fTempIncBufLen + reslen;

SHex := "";
for i := 0 to fTempIncBufLen - 1 do SHex := SHex + IntToHex(fTempIncBuf^[i],2);
AddPacket2Debug(0,SHex);

end; {End while Socket.ReceiveLength > 0 do}
end; {End procedure TTestClass.ClientSocketOnRead}

Буфер fTempIncBuf создается (New) при коннекте и освобождается (Dispose) при дисконнекте.

Т.е суть кода принять данные и записать в журнал их. Но получается что данные коверкаются странным образом. Было приняты 2 блока данных и вот как они выглядели:


0000: 48 7E 91 DD DC 03 F3 0F B0 7A C0 47 3A 20 1C A0 03 2C A3 13
0002: BE 00 1A 74 21 A0 80 CE CE 0F E8 B7 F4 8E EE FF 98 18 60 0F
......
02DE: 53 E1 49 2B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
02E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
.....
0332: 00 00 00 00 00 00 00 00 00 00 00 00

Т.е если обратить внимание, то видны нули в конце. Откуда они взялись - понять не могу. Размер передаваемого блока был 738 байт. Но непонятно откуда поивились лишние нули в конце.

Второй кусок еще более интересно был принят:

0000: 48 7E 91 DD DC 03 F3 0F B0 7A C0 47 3A 20 1C A0 03 2C A3 13
0002: BE 00 1A 74 21 A0 80 CE CE 0F E8 B7 F4 8E EE FF 98 18 60 0F
......
02DE: 53 E1 49 2B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
02E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
......
0330: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0332: 00 00 00 00 00 00 00 00 00 00 00 00 3F 9F E7 28 FB EB C2 F5
0334: F2 FE 70 5B A0 7E 53 E1 49 2B 3F 93 CE 51 F7 D7 85 EB E5 FC
.......
03F4: 48 EE EE 38 47 0E 80 6D 7F 48 EE EE 3B 10 74 B2 FE 91 DD DC
03F6: 46 88 DD

Т.е каким то образом он у меня приклеился в конец первого и принялось все это вместе.

Кто-то может обьяснить причину таких явлений?


 
Bazi   (2005-10-20 13:34) [1]

Забыл добавить: Сервер написан не мною и работает годами. Проблема 100% у меня, только вот не могу понять какая именно. :-(


 
Digitman ©   (2005-10-20 13:46) [2]


> Размер передаваемого блока был 738 байт


а зачем же ты буфер аж в 160 000 байт тогда резервируешь ?

протокол инф.обмена предусматривает какой-либо префикс размера инф.сообщения сервера ?


 
Bazi   (2005-10-20 13:55) [3]


> а зачем же ты буфер аж в 160 000 байт тогда резервируешь
> ?

Потому что дальше пойдут данные побольше. и поэтому взято с запасом.


> протокол инф.обмена предусматривает какой-либо префикс размера
> инф.сообщения сервера ?

Да. Дальше. После этих 2-х фиксированных по длинне служебных пакетов.


 
Digitman ©   (2005-10-20 14:19) [4]


> Bazi   (20.10.05 13:55) [3]


> дальше пойдут данные побольше. и поэтому взято с запасом


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


> После этих 2-х фиксированных по длинне служебных пакетов.


служебные пакеты содержат инф-цию о размере данных, которые сервер будет передавать следом за служебными пакетами ?


 
Slym ©   (2005-10-20 14:51) [5]

Bazi   (20.10.05 13:55) [3]
После этих 2-х фиксированных по длинне служебных пакетов

И где же они фиксированы? Ты опираешься на ReceiveLength, а он может быть далеко не "фиксированным" (склейка/разбиение данных)
Буфер бальшой зачем? принимай фиксированные пакеты в фиксированные буфера, или на крайний случай в динамически расширяемый буфер аля MemoryStream


 
Bazi   (2005-10-20 14:55) [6]


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

Разбер данных не больше 160к. Зависит от типа данных. Как только блок данных я принял - я сбрасываю собирающий буффер в ноль ... Точнее сбрасываю в ноль переменную, в которой фиксируется заполненость буфера.


> служебные пакеты содержат инф-цию о размере данных, которые
> сервер будет передавать следом за служебными пакетами ?

Нет. Каждый новый следующий пакет начинается с двух байтов длинны, а потом и сами данные за ними.


 
Bazi   (2005-10-20 14:58) [7]


> И где же они фиксированы? Ты опираешься на ReceiveLength,
>  а он может быть далеко не "фиксированным" (склейка/разбиение
> данных)
> Буфер бальшой зачем? принимай фиксированные пакеты в фиксированные
> буфера, или на крайний случай в динамически расширяемый
> буфер аля MemoryStream

Та для начала я хочу увидеть, что у меня вообще что-то принимает. Дальше уже буду накапливать и обрабатывать данные. Я вкурсе что данные могут клеиться (разбиватся). Но даже учитывая это явление - я всеравно не могу понять почему я такое принял.


 
Digitman ©   (2005-10-20 15:34) [8]


> Каждый новый следующий пакет начинается с двух байтов длинны


служебный пакет - в их числе ? он ТОЖЕ содержит префикс длины ?

если содержит, то где ты его анализируешь и как используешь ?


 
Bazi   (2005-10-20 15:45) [9]


> Digitman ©   (20.10.05 15:34) [8]

Первые 2 пакета - служебные и фиксированной длинны. Остальные пакеты имееют длинну, записаную в самом начале пакета (первые 2 байта).

Я, после коннекта, принимаю сначала 2 служебных, а потом уже знаю что все пакеты будут иметь длинну в начале


 
Digitman ©   (2005-10-20 16:21) [10]


> Первые 2 пакета - служебные и фиксированной длинны


т.е. 738 байт каждый ?
это именно протоколом регламентировано или это лишь твои домыслы ?


 
Bazi   (2005-10-20 17:32) [11]


> Digitman ©   (20.10.05 16:21) [10]

738 первый и 187 второй. Дальше сервер ждет пока я его буду чтото спрашивать. Это и видно по логу пакетов. Дальше мне ничего не пришло, кроме того, что есть. Только непонятно где у меня ошибка в самом алгоритме приема.


 
Bazi   (2005-10-20 17:34) [12]


> это именно протоколом регламентировано или это лишь твои
> домыслы ?

Протоколом.


 
Digitman ©   (2005-10-20 17:46) [13]


> 738 первый


когда ты ожидаешь первые 738 байт, то и пытайся принять не больше этих 738-ми байт в каждом обработчике OnRead !

цикл свой выкинь.

- перед приемом пакета в 738 байт распредели под него память в 738 байт
- ReceiveLength тебе не нужен
- методом ReceiveBuf пытайся читать ровно столько, сколько осталось до прочтения всех тех 738-ми байт
- размер реально прочитанных данных, возвращенный как результат вызова ReceiveBuf, используй для контроля смещения в твоем 738-байтном буфере

здесь самый важный момент вот какой  : если ты в текущей OnRead-бработке прочитал не все реально поступившие от передатчика данные, то событие OnRead возникнет вновь .. поэтому нет никакого резона пытаться "ждать" все свои 738 (илим сколько-то там) байт в цикле в контексте одного и того же вызванного обработчика


 
Bazi   (2005-10-21 10:43) [14]

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


 
Digitman ©   (2005-10-21 10:56) [15]


> Bazi   (21.10.05 10:43) [14]


да.
похоже на то.


 
Bazi   (2005-10-21 11:12) [16]

ок. еще раз спасибо. :-)



Страницы: 1 вся ветка

Форум: "Сети";
Текущий архив: 2006.01.29;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.062 c
2-1137235739
VadimSpb
2006-01-14 13:48
2006.01.29
Вопрос по дате


15-1136502253
GanibalLector
2006-01-06 02:04
2006.01.29
DLL


2-1137146343
parasolka
2006-01-13 12:59
2006.01.29
Помогите с сервисом


2-1137172222
n0p
2006-01-13 20:10
2006.01.29
Single => String


2-1137407413
Id
2006-01-16 13:30
2006.01.29
IBsql





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский