![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Проблема с переполнением буфера :( [D6, Win2k]
dream © (2005-01-28 10:58:00)Подскажите почему в ниже преведёном коде происходит переполнение буфера при длительной работе ( 10 - 15 мин )
Сам код служит для принятия картинки - файла по сети ( клиент работает на отлично а сервак вылетает :( )
private
{ Private declarations }
Reciving: boolean;
DataSize: integer;
Data: TMemoryStream;
procedure Tvidform.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
var
s, sl: string;
begin
s:= Socket.ReceiveText;
if not Reciving then
begin
SetLength(sl, StrLen(PChar(s))+1); // +1 for the null terminator
StrLCopy(@sl[1], PChar(s), Length(sl)-1);
DataSize:= StrToInt(sl);
Data:= TMemoryStream.Create;
Delete(s, 1, Length(sl));
Reciving:= true;
end;
try
Data.write(s[1], length(s));
if Data.Size = DataSize then
begin
Data.Position:= 0;
Image1.Picture.Bitmap.LoadFromStream(Data);
Data.Free;
Reciving:= false;
end;
except
Data.Free;
end;
end;
Уже второй день мучаюсь , пробывал создавать Data в form create но тогда передача не происходит почему то , я думаю что переполнение происходит при постоянном создании объекта , но если его создать вначале программы как я говорил то картинка не хочет приниматься ...
Digitman (2005-01-28 16:26:00) [1]
> dream (28.01.05 16:07) [12]
надеюсь, ты НЕ упустил ВАЖНОГО комментария
> пример для блок.режима
?
dream (2005-01-28 16:07:00) [2]> Digitman ©
Большое спасибо ! Код работает отлично как и нужно было.
Очень благодарен. :)
dream (2005-01-28 14:51:00) [3]> Digitman © (28.01.05 14:41) [10]
Разобрался ! :) Спасибо за помощь , сейчас буду юзать код , проверять
Digitman (2005-01-28 14:41:00) [4]
> обявление типов я никогда не использовал
А рано или поздно придется.
Ставишь мышиный курсор в зону идентификатора якобы незнакомой тебе директивы type, жмешь F1, читаешь станд.справку до полного просветления в голове либо до потери пульса. Третьего не дано.
Digitman (2005-01-28 14:36:00) [5]
> Я в данном случае работаю в Delphi 6
ты работаешь в СРЕДЕ БЫСТРОЙ РАЗРАБОТКИ ПРОГРАММ.
среда в качестве базового использует ПАСКАЛЬ (точнее Object Pascal) в кач-ыве ЯЗЫКА ПРОГРАММИРОВАНИЯ.
Разницу между СРЕДОЙ РАЗРАБОТКИ ПРОГРАММ и ЯЗЫКОМ ПОРГРАММИРОВАНИЯ осюсяешь или нет ?
dream (2005-01-28 14:27:00) [6]> ты в дан.случае работаешь в Паскале.
Я в данном случае работаю в Delphi 6
И обявление типов я никогда не использовал .. хотя уе писал более менее нормальнае продукты :) бывает и такое
Спасибо за помощь , дальше я думаю сам разберусь
ТехникПТО (2005-01-28 14:16:00) [7]гыы... паскаль сила :)
Digitman (2005-01-28 14:12:00) [8]
> dream (28.01.05 13:46) [5]
> я с паскаля и не начинал
ты в дан.случае работаешь в Паскале.
и ищешь помощи в реализации алгоритма на нем же.
значит, должен как ОТЧЕ НАШ знать правила написания кода в паскале.
> TRecvMode не найден не в справке к delphi не в инете
откуда он там возьмется-то ?
ты же видишь - я использовал директиву type.
значит я объявляю СОБСТВЕННЫЙ тип.
так вот в Паскале объявлять собственные типы допустимо не где попало, а в строго определенных разделах Паскаль-модуля. Надеюсь, ЭТО не подлежит сомнению ?
dream (2005-01-28 13:46:00) [9]Ну во первых я с паскаля и не начинал :)
TRecvMode не найден не в справке к delphi не в инете ... может это и мелочь которую каждый школьник знает но я её к сожалению не могу найти , если не трудно подскажи пожалуйста.
Digitman (2005-01-28 13:30:00) [10]какого ж шута ты занялся криент-серверными технологиями, если даже Паскаль не знаешь ?
dream (2005-01-28 12:41:00) [11]> Digitman © (28.01.05 12:26) [1]
Жалуеться на TRecvMode не могу понять что это и
type
TRecvMode = (rmImageSize, rmImageData);
то же что то не получаеться вставить :(
dream (2005-01-28 12:37:00) [12]> Digitman © (28.01.05 12:26) [1]
Спасибо попробую
Digitman (2005-01-28 12:26:00) [13]передача/прием бин.данных (размер транслируемого потока и собственно следующие за размером данные картинки в потоке) с пом. методов SendText/ReceiveText как минимум неуместны
type
TRecvMode = (rmImageSize, rmImageData);
private
{ Private declarations }
Mode: TRecvMode;
BytesNeedToRead: Integer;
ImageSize: Integer;
ImageData: TMemoryStream;
procedure Tvidform.ClientSocket1Connect(Sender: TObject;
Socket: TCustomWinSocket);
begin
Mode := rmImageSize;
BytesNeedToRead := SizeOf(ImageSize);
end;
procedure Tvidform.ClientSocket1Disconnect(Sender: TObject;
Socket: TCustomWinSocket);
begin
FreeAndNil(ImageData);
end;
procedure Tvidform.ClientSocket1Error(Sender: TObject;
Socket: TCustomWinSocket; ErrorCode: Integer);
begin
FreeAndNil(ImageData);
ErrorCode := 0;
end;
procedure Tvidform.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
var
len : Integer;
begin
case Mode of
rmImageSize:
begin
len := Socket.ReceiveBuf(PByteArray(@ImageSize)[SizeOf(ImageSize) - BytesNeedToRead], BytesNeedToRead);
Dec(BytesNeedToRead, len);
if BytesNeedToRead = 0 then
begin
ImageData := TMemoryStream.Create;
ImageData.Size := ImageSize;
Mode := rmImageData;
BytesNeedToRead := ImageSize;
end;
end;
rmImageData:
begin
len := Socket.ReceiveBuf(PByteArray(ImageData.Memory)[ImageSize - BytesNeedToRead], BytesNeedToRead);
Dec(BytesNeedToRead, len);
if BytesNeedToRead = 0 then
begin
try
try
Image1.Picture.Bitmap.LoadFromStream(ImageData);
except
Socket.Close;
end;
Mode := rmImageSize;
BytesNeedToRead := SizeOf(ImageSize);
finally
FreeAndNil(ImageData);
end;
end;
end;
end;
s:= Socket.ReceiveText;
if not Reciving then
begin
SetLength(sl, StrLen(PChar(s))+1); // +1 for the null terminator
StrLCopy(@sl[1], PChar(s), Length(sl)-1);
DataSize:= StrToInt(sl);
Data:= TMemoryStream.Create;
Delete(s, 1, Length(sl));
Reciving:= true;
end;
try
Data.write(s[1], length(s));
if Data.Size = DataSize then
begin
Data.Position:= 0;
Image1.Picture.Bitmap.LoadFromStream(Data);
Data.Free;
Reciving:= false;
end;
except
Data.Free;
end;
end;
..
передатчик же (пример для блок.режима) делает так :
var
ImageSize: Integer;
ImageData: TMemoryStream;
..
//создает поток и грузит в него данные картинки
..
ImageSize := ImageData.Size;
Socket.SendBuf(ImageSize, SizeOf(ImageSize)); //4 байта - размер потока
Socket.SendBuf(ImageData.Memory^, ImageSize); //собственно картинка размером ImageSize байт