![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Проблема с TClientSocket. "Непонятные" явления.
Bazi © (2005-10-20 13:33:00)Мастера, помогите мне найти ошибку. Суть в том, что я принимаю некие данные, но они получаються испорчеными.
Код следующий:
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 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-21 11:12:00) [1]ок. еще раз спасибо. :-)
Digitman (2005-10-21 10:56:00) [2]
> Bazi (21.10.05 10:43) [14]
да.
похоже на то.
Bazi (2005-10-21 10:43:00) [3]Digitman, спасибо. Попробую...
Получается что проблемы у меня были из-за того, что я в цикле пытался забрать данные?
Digitman (2005-10-20 17:46:00) [4]
> 738 первый
когда ты ожидаешь первые 738 байт, то и пытайся принять не больше этих 738-ми байт в каждом обработчике OnRead !
цикл свой выкинь.
- перед приемом пакета в 738 байт распредели под него память в 738 байт
- ReceiveLength тебе не нужен
- методом ReceiveBuf пытайся читать ровно столько, сколько осталось до прочтения всех тех 738-ми байт
- размер реально прочитанных данных, возвращенный как результат вызова ReceiveBuf, используй для контроля смещения в твоем 738-байтном буфере
здесь самый важный момент вот какой : если ты в текущей OnRead-бработке прочитал не все реально поступившие от передатчика данные, то событие OnRead возникнет вновь .. поэтому нет никакого резона пытаться "ждать" все свои 738 (илим сколько-то там) байт в цикле в контексте одного и того же вызванного обработчика
Bazi (2005-10-20 17:34:00) [5]
> это именно протоколом регламентировано или это лишь твои
> домыслы ?
Протоколом.
Bazi (2005-10-20 17:32:00) [6]
> Digitman © (20.10.05 16:21) [10]
738 первый и 187 второй. Дальше сервер ждет пока я его буду чтото спрашивать. Это и видно по логу пакетов. Дальше мне ничего не пришло, кроме того, что есть. Только непонятно где у меня ошибка в самом алгоритме приема.
Digitman (2005-10-20 16:21:00) [7]
> Первые 2 пакета - служебные и фиксированной длинны
т.е. 738 байт каждый ?
это именно протоколом регламентировано или это лишь твои домыслы ?
Bazi (2005-10-20 15:45:00) [8]
> Digitman © (20.10.05 15:34) [8]
Первые 2 пакета - служебные и фиксированной длинны. Остальные пакеты имееют длинну, записаную в самом начале пакета (первые 2 байта).
Я, после коннекта, принимаю сначала 2 служебных, а потом уже знаю что все пакеты будут иметь длинну в начале
Digitman (2005-10-20 15:34:00) [9]
> Каждый новый следующий пакет начинается с двух байтов длинны
служебный пакет - в их числе ? он ТОЖЕ содержит префикс длины ?
если содержит, то где ты его анализируешь и как используешь ?
Bazi (2005-10-20 14:58:00) [10]
> И где же они фиксированы? Ты опираешься на ReceiveLength,
> а он может быть далеко не "фиксированным" (склейка/разбиение
> данных)
> Буфер бальшой зачем? принимай фиксированные пакеты в фиксированные
> буфера, или на крайний случай в динамически расширяемый
> буфер аля MemoryStream
Та для начала я хочу увидеть, что у меня вообще что-то принимает. Дальше уже буду накапливать и обрабатывать данные. Я вкурсе что данные могут клеиться (разбиватся). Но даже учитывая это явление - я всеравно не могу понять почему я такое принял.
Bazi (2005-10-20 14:55:00) [11]
> побольше это сколько ?
> "запас" от балды взят ?
> откуда тебе известно, сколько данных в конечном итоге передаст
> сервер за весь сеанс твоего коннекта с ним ?
Разбер данных не больше 160к. Зависит от типа данных. Как только блок данных я принял - я сбрасываю собирающий буффер в ноль ... Точнее сбрасываю в ноль переменную, в которой фиксируется заполненость буфера.
> служебные пакеты содержат инф-цию о размере данных, которые
> сервер будет передавать следом за служебными пакетами ?
Нет. Каждый новый следующий пакет начинается с двух байтов длинны, а потом и сами данные за ними.
Slym (2005-10-20 14:51:00) [12]Bazi (20.10.05 13:55) [3]
После этих 2-х фиксированных по длинне служебных пакетов
И где же они фиксированы? Ты опираешься на ReceiveLength, а он может быть далеко не "фиксированным" (склейка/разбиение данных)
Буфер бальшой зачем? принимай фиксированные пакеты в фиксированные буфера, или на крайний случай в динамически расширяемый буфер аля MemoryStream
Digitman (2005-10-20 14:19:00) [13]
> Bazi (20.10.05 13:55) [3]
> дальше пойдут данные побольше. и поэтому взято с запасом
побольше это сколько ?
"запас" от балды взят ?
откуда тебе известно, сколько данных в конечном итоге передаст сервер за весь сеанс твоего коннекта с ним ?
> После этих 2-х фиксированных по длинне служебных пакетов.
служебные пакеты содержат инф-цию о размере данных, которые сервер будет передавать следом за служебными пакетами ?
Bazi (2005-10-20 13:55:00) [14]
> а зачем же ты буфер аж в 160 000 байт тогда резервируешь
> ?
Потому что дальше пойдут данные побольше. и поэтому взято с запасом.
> протокол инф.обмена предусматривает какой-либо префикс размера
> инф.сообщения сервера ?
Да. Дальше. После этих 2-х фиксированных по длинне служебных пакетов.
Digitman (2005-10-20 13:46:00) [15]
> Размер передаваемого блока был 738 байт
а зачем же ты буфер аж в 160 000 байт тогда резервируешь ?
протокол инф.обмена предусматривает какой-либо префикс размера инф.сообщения сервера ?
Bazi (2005-10-20 13:34:00) [16]Забыл добавить: Сервер написан не мною и работает годами. Проблема 100% у меня, только вот не могу понять какая именно. :-(