![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Delphi пример пересылки изображения через сеть
Knight © (2004-11-07 01:25:00)У кого может завалялся? (ServerSocket-ClientSocket)
able (2004-11-10 00:36:00) [1]Странно. Видел пару чатов, работающих на NMUDP и ничего вроде..
Verg (2004-11-09 21:06:00) [2]Вот попробуй для прикола. Особенно впечатляет, когда не из под Дельфи запускаешь exe-шник и нажимешь Button2 :)
procedure TForm1.Button2Click(Sender: TObject);
var ms:TMemoryStream;
S : string;
begin
ms:=TMemoryStream.Create;
try
Setlength(S, 5000);
Ms.WriteBuffer(S[1], length(S));
NMUDP1.SendStream(Ms);
finally
Ms.Free;
end;
end;
> А глюки переходят от версии к версии или их правят? (Delphi
> 6)
Помоему Borland вообще "забил" на FastNet. Для меня, например, решающим в свое время стал факт отсутствия исходников.
Knight (2004-11-09 20:58:00) [3]
> [19] Verg © (09.11.04 20:51)
> Кстати, в NMUDP -шном SendStream был како-то "замечательный"
> глюк.
А глюки переходят от версии к версии или их правят? (Delphi 6)
Verg (2004-11-09 20:51:00) [4]Кстати, в NMUDP -шном SendStream был како-то "замечательный" глюк.
Когда-то даже разбирался в чем дело. Что-то там с буферами фиксированного (небольшого) размера, расположенными в стеке для чтения из потока.
При размере передаваемого потока больше некоторой величины (2048 байт, что ли) весь процесс с "грохотом" рухал по причине затирания стека содержимым потока...
Knight (2004-11-09 20:39:00) [5]
> [17] Verg © (09.11.04 20:07)
Всё пошло... я на приёме данных Buff^ сделал, а на отправке изменить забыл... вот он в ссылках и запутался :)))
СПАСИБО.
Verg (2004-11-09 20:07:00) [6]
> Кстати, он и не должен так работать, т.к. Buffer это указатель,
> а у меня PChar... т.е. всё верно... пример нашёл в хэлпе,
> один к одному... но не пашет :(
Честно говоря не понял что ты сказал.
У тебя Buff - это pchar, т.е. указатель.
TMemoryStrea.Read( var Buffer; Count : integer);
Т.е. Buffer - это ссылка.
Поэтому,
ms.Read(Buff^,NumberBytes);
можно и
ms.Read(Buff[0], NumberBytes);
что есть суть одно и тоже
И никак иначе!
Кстати, в Help-e пример вообще с string-ом, а не с pchar.
Knight (2004-11-09 19:56:00) [7]
> [14] Verg © (09.11.04 16:51)
> > // ms.Read(Buff^,NumberBytes);
Кстати, он и не должен так работать, т.к. Buffer это указатель, а у меня PChar... т.е. всё верно... пример нашёл в хэлпе, один к одному... но не пашет :(
Knight (2004-11-09 19:31:00) [8]
> [14] Verg © (09.11.04 16:51)
> > // ms.Read(Buff^,NumberBytes);
Так вообще не работает... у меня хоть в Buff данные, а тут мусор...
Verg (2004-11-09 16:51:00) [9]Для начала
> // ms.Read( Buff^,NumberBytes);
Knight (2004-11-09 16:23:00) [10]В чём проблема? Стоит раскомментировать строку с Read... как начинается сбой по памяти... причём в Buff верное значение полученной строки... но при этом ms.Free начинает вызываться 2 раза подряд.
procedure TMainForm.NMUDPDataReceived(Sender: TComponent; NumberBytes: Integer; FromIP: String; Port: Integer);
var ms:TMemoryStream;
Buff:PChar;
begin
ms:=TMemoryStream.Create;
try
NMUDP.ReadStream(ms);
Buff:=AllocMem(NumberBytes+1);
ms.Position:=0;
// ms.Read(Buff,NumberBytes);
FreeMem(Buff);
finally
ms.Free;
end;
end;
VMcL (2004-11-09 07:22:00) [11]>> Knight © (08.11.04 16:32) [11]
Боюсь, с изображением такой "номер" не прокатит. Разве что, если его закодировать, например, в BASE64. Только нужно иметь в виду, что в BASE64 данные на ~33% больше занимать будут.
Knight (2004-11-08 16:32:00) [12]
> [10] VMcL © (08.11.04 07:31)
> Пример маркера - это HTTP запрос. Признаком конца заголовка
> запроса служит двойной перевод каретки (#10#10, если не
> ошибаюсь);
А это мысль... так и сделаю.
Всем, СПАСИБО! :)
VMcL (2004-11-08 07:31:00) [13]>> Knight © (07.11.04 21:32) [9]
Если прикручивать инфу "сколько", то это метод [3], [4]. Пример маркера - это HTTP запрос. Признаком конца заголовка запроса служит двойной перевод каретки (#10#10, если не ошибаюсь); и это работает корректно, потому что в самом заголовке такая последовательность встретиться не может.
Knight (2004-11-07 21:32:00) [14]
> [8] VMcL © (07.11.04 20:49)
> Некоторая последовательность бит, которая не может встретиться
> в передаваемых данных.
Т.е. в начале данных прикручивать инфу о том, что это и сколько этого должно быть? Если да, то я эту мысль уже думаю... %)
VMcL (2004-11-07 20:49:00) [15]>> Knight © (07.11.04 16:11) [7]
Некоторая последовательность бит, которая не может встретиться в передаваемых данных.
Knight (2004-11-07 16:11:00) [16]
> [6] VMcL © (07.11.04 13:08)
> Необязательно. Можно, например, пользоваться маркером.
А это что такое? Первый раз слышу...
VMcL (2004-11-07 13:08:00) [17]>> Knight © (07.11.04 04:08) [5]
Необязательно. Можно, например, пользоваться маркером.
Knight (2004-11-07 04:08:00) [18]
> [3] PEAKTOP © (07.11.04 03:45)
Пример, на базе которого это сделано я нашёл... поэтому вопрос и появился... неужели нельзя как-то иначе? Обязательно, сперва отправлять размер, а потом склеивать Socket.ReceiveText'ы?
PEAKTOP (2004-11-07 03:50:00) [19]а потом на клиенте читал:
implementation
uses
jpeg;
.....
var
RecivingDesktop :Boolean = false;
.....
procedure TZeandgePropertiesForm.ClientSocketRead(Sender: TObject; Socket: TCustomWinSocket);
var
s, sl :string;
count :longint;
begin
s:= Socket.ReceiveText;
if not RecivingDesktop then
begin
count := 0;
Gauge.Visible := FALSE;
Label1.Caption := '';
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));
RecivingDesktop := TRUE;
end;
try
count := count + 1;
Data.Write(s[1], length(s));
Gauge.Progress := Round(count/DataSize*100);
Gauge.Visible := TRUE;
Label1.Caption := 'reciving data ....';
if Data.Size = DataSize then
begin
Gauge.Visible := FALSE;
Data.Position := 0;
DesktopImage.Picture.Graphic := TJPEGImage.Create;
DesktopImage.Picture.Graphic.LoadFromStream(Data);
DesktopImage.Width := DesktopImage.Picture.Graphic.Width;
DesktopImage.Height := DesktopImage.Picture.Graphic.Height;
RecivingDesktop := FALSE;
Socket.Close;
Label1.Caption := 'READY !';
end;
except
Data.Free;
end;
end;
PEAKTOP (2004-11-07 03:45:00) [20]1) Делаешь скрин-шот десктопа (смотри ФАК)
2) Сжимаешь ее на клиенте в jpeg
3) Передаешь jpeg по сети потоком.
Я когда-то делал так:
implementation
uses
jpeg;
........
procedure TMainForm.ServerSocketClientRead(
Sender: TObject; Socket: TCustomWinSocket);
var
ms :TMemoryStream;
jpg :TJPEGImage;
img :TImage;
DC :HDC;
s :string;
begin
if Socket.ReceiveText='PHOTO' then
try
ms := TMemoryStream.Create;
img := TImage.Create(NIL);
img.Picture.Bitmap.Height := Screen.Height;
img.Picture.Bitmap.Width := Screen.Width;
DC := GetDC(HWND_DESKTOP);
bitblt(img.Picture.Bitmap.Canvas.Handle, 0,0, Screen.Width, Screen.Height, DC, 0, 0, SRCCOPY);
jpg := TJPEGImage.Create;
jpg.Assign(img.Picture.Bitmap);
img.Free;
jpg.Compress;
jpg.SaveToStream(ms);
ms.Position:= 0;
Socket.SendText(IntToStr(ms.Size) + #0);
Socket.SendStream(ms);
jpg.Free;
except
ms.Free;
end;
end;