Форум: "Сети";
Текущий архив: 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