-
Здраствуйте, уважаемые форумчани.
Написала программульку которая делает на удаленной машине скриншот и передает его на мой. Но есть две проблемы:
1. При отображении изображения в image32 происходит какаето ерунда - такое ощущение, что по сети передается не одно изображение, а целая куча, причем с каждым разом все меньше и меньше их параметры(ширина и высота). В итоге в image32 сразу видно несколько, отличных по размеру, копий изображения.
2. Вторая проблема заключается в том, что не могу передать копию удаленного экрана во всем размере ,хотя и кодирую его в jpg. Приходиться передавать уменьшенную копию, к примеру 500 на 500. Можно и побольше, но качество надо уменьшить. Если передаю во весь размер Delphi выдает ошибку - переполнения буфера.
В работе использую компоненты indy для работы с udp. Помогите разобраться...
Может быть непонятно объяснила проблемы - поэтому прикрепляю два файла. Когда протестируете все увидите сами...
Заранее спасибо...
-
1. Выкинь UDP, а пользуй TCP 2. Прикрепленных файлов лично я не увидел :) Твоя проблема состоит в том, что UDP: вопервых не гарантирует доставку; вовторых имеет ограничение по размеру кадра чуть меньше 64Кб. Если даже будешь разбивать изображение на части то UDP не гарантирует, что посланная тобой последовательность придет в том же порядке как и посылалась!
Решение твоей задачи:
Первое 1. Используй TCP и будет Вам щастье :)
Второе 1. Не морочь голову поставь RAdmin :)
Если же выберешь первое решение, то есть компоненты T(Server/Client)Socket в [Delphi]\Source\VCL\SCKTCOMP.PAS ну или ИНДИ :) Смотря какая стоит задача. Можно и на Winsock-е написать :)
-
Оффтоп: Вы часом с ikot-ом не родственники? :)
-
> Написала программульку которая делает на удаленной машине > скриншот и передает его на мой. Но есть две проблемы:
Стянула код неизвестно откуда и ес-но в нем ничего не понимаю, поэтому есть две проблемы:
> 1. При отображении изображения в image32 происходит какаето > ерунда - такое ощущение, что по сети передается не одно > изображение, а целая куча, причем с каждым разом все меньше > и меньше их параметры(ширина и высота). В итоге в image32 > сразу видно несколько, отличных по размеру, копий изображения. >
Скорее всего передаются только изменившиеся куски скрина
> 2. Вторая проблема заключается в том, что не могу передать > копию удаленного экрана во всем размере ,хотя и кодирую > его в jpg. Приходиться передавать уменьшенную копию, к примеру > 500 на 500. Можно и побольше, но качество надо уменьшить. > Если передаю во весь размер Delphi выдает ошибку - переполнения > буфера.
У дельфи очень маленький буфер, туда целый экран не влезет ;)
> Может быть непонятно объяснила проблемы - поэтому прикрепляю > два файла. Когда протестируете все увидите сами...
Хм... тут совсем интересно. И куда их прикрепила? )))
-
> Оффтоп: Вы часом с ikot-ом не родственники? :)
C чего ты это взял. Если судить по твоим словам, то на этом форуме почти все являются родственниками.. Большая у нас тогда получается семья.
-
> > Написала программульку которая делает на удаленной машине > > скриншот и передает его на мой. Но есть две проблемы:Стянула > код неизвестно откуда и ес-но в нем ничего не понимаю, поэтому > есть две проблемы:> 1. При отображении изображения в image32 > происходит какаето > ерунда - такое ощущение, что по сети > передается не одно > изображение, а целая куча, причем с > каждым разом все меньше > и меньше их параметры(ширина и > высота). В итоге в image32 > сразу видно несколько, отличных > по размеру, копий изображения.> Скорее всего передаются > только изменившиеся куски скрина> 2. Вторая проблема заключается > в том, что не могу передать > копию удаленного экрана во > всем размере ,хотя и кодирую > его в jpg. Приходиться передавать > уменьшенную копию, к примеру > 500 на 500. Можно и побольше, > но качество надо уменьшить.> Если передаю во весь размер > Delphi выдает ошибку - переполнения > буфера. У дельфи очень > маленький буфер, туда целый экран не влезет ;)> Может быть > непонятно объяснила проблемы - поэтому прикрепляю > два > файла. Когда протестируете все увидите сами...Хм... тут > совсем интересно. И куда их прикрепила? )))
Зачем грубить. Вообще то форумы для того и служат, чтобы спросить совета.
RADMIN - это хорошо, но хочеться и самой попробовать создать что-то подобное.
На щет исходников - дело в том, что аналогичное сообщение оставила и на другом форуме. Как здесь прикреплять файлы не знаю, поэтому выставляю исходники в письменном виде. Смотри сообщение ниже:
-
Это сервер
unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ScktComp, Jpeg, ExtCtrls, IdBaseComponent, IdComponent, IdUDPBase, IdUDPClient;
type TForm1 = class(TForm) ServerSocket1: TServerSocket; IdUDPClient1: TIdUDPClient; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure ServerSocket1ClientRead(Sender: TObject; Socket: TCustomWinSocket); procedure ServerSocket1ClientConnect(Sender: TObject; Socket: TCustomWinSocket); procedure ServerSocket1ClientDisconnect(Sender: TObject; Socket: TCustomWinSocket); private { Private declarations } public { Public declarations } end;
var Form1: TForm1;
implementation
{$R *.dfm}
procedure ScreenShot; var bmp: TBitmap; DC: HDC; Canvas: TCanvas; MemStream : TMemoryStream; jpg: TJpegImage;
begin DC := GetDC(0); Bmp := TBitmap.Create; Bmp.PixelFormat:=pf16bit; Bmp.Width := Screen.Width; Bmp.Height := Screen.Height;
Canvas := TCanvas.Create; Canvas.Handle := DC;
Bmp.Canvas.CopyRect(Screen.DesktopRect, Canvas, Screen.DesktopRect);
jpg := TJpegImage.Create; jpg.Assign( bmp );
bmp.Width := 500 ; bmp.Height:= 500; bmp.Canvas.StretchDraw( bmp.Canvas.Cliprect, jpg );
jpg.Assign( bmp ); jpg.CompressionQuality:=45;
MemStream:= TMemoryStream.Create;
jpg.SaveToStream(MemStream);
form1.idUDPClient1.SendBuffer(MemStream.Memory^,MemStream.Size);
MemStream.Free; jpg.Free; bmp.Free; Canvas.Free; end;
procedure TForm1.FormCreate(Sender: TObject); begin serverSocket1.Active:=true;
end;
procedure TForm1.FormDestroy(Sender: TObject); begin ServerSocket1.Active:=false;
end;
procedure TForm1.ServerSocket1ClientRead(Sender: TObject; Socket: TCustomWinSocket); var reseiveText, reseiveText1, cmd:string; lockin:boolean; begin
reseiveText:=Socket.ReceiveText; reseiveText1:=reseiveText;
if length(reseiveText)<=6 then cmd:=reseiveText else begin reseiveText:=copy(reseiveText, 8, length(reseiveText)); cmd:=copy(reseiveText1, 1, 6); end;
if cmd = 'screen' then ScreenShot;
end;
procedure TForm1.ServerSocket1ClientConnect(Sender: TObject; Socket: TCustomWinSocket); begin form1.Caption:='Connected...'; form1.IdUDPClient1.Port:=4001; form1.IdUDPClient1.Host:=Socket.RemoteHost; form1.IdUDPClient1.Active:=true; end;
procedure TForm1.ServerSocket1ClientDisconnect(Sender: TObject; Socket: TCustomWinSocket); begin form1.Caption:='Disconnect...'; end;
end.
-
Это клиент
unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ScktComp,jpeg, Buttons, IdBaseComponent, IdComponent, IdUDPBase, IdUDPServer, IdSocketHandle, unit3;
type TForm1 = class(TForm) ClientSocket1: TClientSocket; Label1: TLabel; Label2: TLabel; port: TEdit; ip: TEdit; Button1: TButton; Button2: TButton; BitBtn8: TBitBtn; IdUDPServer1: TIdUDPServer; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure ClientSocket1Connect(Sender: TObject; Socket: TCustomWinSocket); procedure ClientSocket1Disconnect(Sender: TObject; Socket: TCustomWinSocket); procedure Button3Click(Sender: TObject); procedure BitBtn8Click(Sender: TObject); procedure IdUDPServer1UDPRead(Sender: TObject; AData: TStream; ABinding: TIdSocketHandle); private
{ Private declarations } public { Public declarations } end;
var Form1: TForm1; MemoryStream : TMemoryStream;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject); begin ClientSocket1.Port:=strtoint(port.Text); ClientSocket1.Address:=ip.Text; ClientSocket1.Active:=true; end;
procedure TForm1.Button2Click(Sender: TObject); begin ClientSocket1.Active:=false; end;
procedure TForm1.FormDestroy(Sender: TObject); begin ClientSocket1.Close; ClientSocket1.Active:=false; end;
procedure TForm1.ClientSocket1Connect(Sender: TObject; Socket: TCustomWinSocket); begin form1.Caption:='Connected!'; end;
procedure TForm1.ClientSocket1Disconnect(Sender: TObject; Socket: TCustomWinSocket); begin form1.Caption:='Disconnect'; end;
procedure TForm1.Button3Click(Sender: TObject); begin ClientSocket1.Socket.SendText('screen'); end;
procedure TForm1.BitBtn8Click(Sender: TObject); begin ClientSocket1.Socket.SendText('screen'); form3.show; end;
procedure TForm1.IdUDPServer1UDPRead(Sender: TObject; AData: TStream; ABinding: TIdSocketHandle); begin MemoryStream:= TMemoryStream.Create; MemoryStream.CopyFrom(AData, AData.Size); MemoryStream.SaveToFile('C:\logo.jpg'); form3.Image321.Bitmap.LoadFromFile('C:\logo.jpg'); if form3.Showing then begin MemoryStream.Free; ClientSocket1.Socket.SendText('screen'); end; end; end.
-
> olchick © (03.06.09 11:39) [5] > Зачем грубить.
Увольтес, где???
-
Но есть две проблемы: Стянула код неизвестно откуда и ес-но в нем ничего не понимаю, поэтому > есть две проблемы: 1. При отображении изображения в image32 > происходит какаето > ерунда - такое ощущение, что по сети > передается не одно > изображение, а целая куча, причем с > каждым разом все меньше > и меньше их параметры(ширина и > высота). В итоге в image32 > сразу видно несколько, отличных > по размеру, копий изображения.> Скорее всего передаются > только изменившиеся куски скрина> 2. Вторая проблема заключается > в том, что не могу передать > копию удаленного экрана во > всем размере ,хотя и кодирую > его в jpg. Приходиться передавать > уменьшенную копию, к примеру > 500 на 500. Можно и побольше, > но качество надо уменьшить.> Если передаю во весь размер > Delphi выдает ошибку - переполнения > буфера. У дельфи очень > маленький буфер, туда целый экран не влезет ;)> Может быть > непонятно объяснила проблемы - поэтому прикрепляю > два > файла. Когда протестируете все увидите сами...Хм... тут > совсем интересно. И куда их прикрепила? )))
Вы тоже удовольтесь и прочитайте сами свои слова
-
> Вы тоже удовольтесь и прочитайте сами свои слова
И где тут груботсь? Изволите утверждать что он самолично написан?
-
> И где тут груботсь? Изволите утверждать что он самолично > написан?
никто не говорит об этом, а если Вы не понимаете о чем кокретно иде речь, то прошу Вас обратить внимание на эту фразу: ес-но в нем ничего не понимаю
Ладно, проехали...
-
> Ладно, проехали...
Проехали, так проехали...
1. Зачем серверу форма?
-
>olchick © Судя по исходнику, это полный бред! Зачем ты создаешь ClientSocket и ServerSocket если все равно посылаеш через UDP!?!?!?!?!?!?! Да этот форум отличается тем, чтобы давать направление куда копать! http://book.itep.ru -там найдешь описание UDP и TCP! твоя задача: 1. Создать "Запись" типа: Индентификатор+Команда+РазмерПередаваемыхДанных; 2. Сервер обрабатыевает команду и отсылает ответ на клиент. 3. TCP - это потоковый протокол, данные надо складывать в буфер, UDP - диаграммный протокол, и тебе он не подходит! 4. Выкинь свой исходник и начни изучать как устроены протоколы передачи данных, чтобы не задавать вопросов, почему у меня вышеописанный бред не работает.
-
> Зачем ты создаешь ClientSocket и ServerSocket если все равно > посылаеш через UDP!?!?!?!?!?!?!
А через него она передает адрес клиента, на этом его миссия заканчивается...
-
Всем БОЛЬШОЕ СПАСИБО за помощь ...
-
Было приятно советоваться с вами - дЖЕНТЕЛЬМЕНЫ
-
>olchick ©
А как ты проверяешь, послала ли ты данные или нет? У тебя нет обработки ошибок!
Чтобы ты поняла опишу технологию, как должна была бы выглядеть твоя программа:
1. Программа на удаленном ПК открывает УДП порт к примеру 8888 и слушает когда придет пакет от сервера. 2. Ты запуская свою программу администрирования отсылаешь Броадкаст пакет(можно раз в 15 сек) с данными своего (ДНС-Имени или IP-адрес)+Порт на свой ТСП сервер. 3. Клиент принимая пакет пытается соединится с твоим сервером. А далее ты создаешь список клиентов и далее уже отсылаеш и принимаеш данные по ТСП протоколу. А там нужно отделять одно сообщение(изображение) пакет от другого. 4. Дальше делаеш с данными все что тебе заблагорассудиться...
А передача команд строковыми переменными, большая расточительность. ИМХО!
-
[15] Вот, :( обиделась.... потом через 7 минут зашла [16] - ничего нет... и опять обиделась...
-
ну чего обижаться... Мы же объясняли, что не тот протокол... Или девушка ждала исходный программы ее мечты? пускай напишет, что она хотела...
-
> ну чего обижаться...Мы же объясняли, что не тот протокол. > ..Или девушка ждала исходный программы ее мечты?пускай напишет, > что она хотела...
Как передать по протоколу TCP скриншот - не составляет проблемы. Почему выбран был именно UDP? объясняю:
1. Для локальной сети не думаю, что это принципиально важно, хотя может быть и важно. Дело в том, что TCP - довольно медленный по сравнению с UDP. И если все таки передавать по TCP - возникает только один вопрос: Зачем лишние проверки и подтверждения доставленна ли картинка или нет. Видь при этом мы теряем в скорости...
2. Сначала моя программа была ориентирована на Tcp, но в связи с несколькими возникшимся проблемами, а именно: низкая скорость передачи, мерцание при смене картинки в image, и таже проблема, о которой я писала в самом первом сообщении с постоянным уменьшением картинки, если отображать принятую картинку в image, а потом вдруг изменить размер image...
Все это, а также, может быть и то, что такие проблемы возникали не только у меня, но и у других, натолкнули меня на мысль с UDP. Тем более, что я не первая кто использует его именно в этих целях...
Пробовала также через протокол RDP, но ничего не вышло, была ошибка в компоненте, которую я, и судя по другим форумам, не только я, не знала как исправить.
По поводу ClientSocket и ServerSocket, что Вы их обнаружили у меня в коде, то это связанно с другими функциями моей программы. Хотя наверняка можно было и без этих компонент обойтись спокойно, еще раз повторюсь - сначала программа делалась именно для TCP. Зачем на сервере ФОРМА, то это тоже связанно с другими функциями моей горе-программы. И еще одно, я полностью согласна, что надо осуществлять передачу, используя таймер, но это не решает проблему. А на мысль с условием if form3.showing then ... натолкнулась на одном из форумов. По моему хорошее решение и не надо никаких таймеров - результат тот же. P.S. проверенно.
Почитав документацию, выяснила, что РАДМИН написан для работы с TCP, но он же использует специальный драйвер - и это его фишка.
Испробовала также код, приведенный код в вашем же форуме с передачей скриншота, и опять все те же, описанные выше ошибки.
Или взять скажем уже готовые программы для удаленного администрирования - у многих них при разворачивании на весь экран происходят похожие проблемы. И не только при разворачивании.
Что хотелось от всех Вас, чтобы вы указали в чем возможная проблема, а то на других форумах так и не нашла ответа. может проблема именно в приеме - я не знаю. Поэтому и спрашиваю у экспертов.
-
Можно конечно для ускорения передачи по TCP использовать следующий прием: сняли скриншот- разбиваем поток на несколько частей и шлем паралельно их на клиент. Но как это сделать, а главное как потом собрать все воединно не знаю.
-
> разбиваем поток на несколько частей
Этого делать не нужно, да и не поможет! Основная задержка при сжатии из БМП в ДЖИПЕГ. если у тебя 100Мбит то 100000000/8=1250000 Кбайт/с достаточно для того чтобы посылать приблизительно 5-8 кадров 1024:768 в секунду.
-
> Можно конечно для ускорения передачи по TCP использовать > следующий прием: сняли скриншот- разбиваем поток на несколько > частей и шлем паралельно их на клиент. > Но как это сделать, а главное как потом собрать все воединно > не знаю.
И почему оно будет быстрее?
-
> если у тебя 100Мбит то 100000000/8=1250000 Кбайт/с достаточно > для того чтобы посылать приблизительно 5-8 кадров 1024:768 > в секунду.
Положим всю сеть... :)
-
В джипег конечно :) РАдмин использует алгоритм анализа изменения изображения на экране, и посылает только то, что изменилось. Я дал ссылку выше, там сайт с протоколами и описаниями видео форматов МПЕГ. принципы работы. почитай может поможет. Ну и наверное не обойдется без какого-нибудь драйвера прослойки между основными видео драйверами.
-
> Положим всю сеть... :)
Конечно, но если делать скриншотами, то только так :)
-
1250000 байт/с :)
-
> Конечно, но если делать скриншотами, то только так :)
А так не надо делать, а она вот уперлась :) выбрали и все тут...
-
> Этого делать не нужно, да и не поможет!Основная задержка > при сжатии из БМП в ДЖИПЕГ. если у тебя 100Мбит то 100000000/8=1250000 > Кбайт/с достаточно для того чтобы посылать приблизительно > 5-8 кадров 1024:768 в секунду.
у вас на форуме нашла ветвь intel jpeg libruary и сокеты, попробывала сжимать с помощью этой библиотеки вродибы получилось - все сжалось, но есть проблема: эта библиотека вродибы не позволяет сохрянять данные в поток, поэтому приходиться сохранять сначала в виде файла, потом в переменную jpg : Tjpegimage загружаем изображение из файла, а только потом сохраняем все в поток. Но похоже, что обчинка выделки не стоит. Или я опять что не так делаю.
Буду разбираться с вашими советами и ссылками и копать в сторону принципаов радмина.
Senk you very much...
-
> Или я опять что не так делаю
Именно.
Передавать следует не весь шот, а только его изменения отн-но предыдущего шота.
Огромную помощь в этом оказывает display mirror driver.
-
> Огромную помощь в этом оказывает display mirror driver.
а теперь подробнее, пожалуйста.
что это такое, где его взять и главное как этим пользоваться?
-
-
> olchick ©
> Сначала моя программа была ориентирована на Tcp, но в связи > с несколькими возникшимся проблемами, а именно: низкая скорость > передачи, мерцание при смене картинки в image
Я могу передать не то что по TCP, а даже по HTTP кадров 200 в секунду. Так что в UDP смысла нет.
-
> olchick © (03.06.09 17:05) [29]
> у вас на форуме нашла ветвь intel jpeg libruary и сокеты, > попробывала сжимать с помощью этой библиотеки вродибы получилось > - все сжалось, но есть проблема: эта библиотека вродибы > не позволяет сохрянять данные в поток
Она умеет и сжимать и разжимать данные в памяти, надо не слепо копировать код а посмотреть хотя бы заголовочный файл библиотеки. Прикрутить все это затем к TStream не сложно.
-
> а даже по HTTP кадров 200 в секунду
О_о интересно посмотреть на скрипт)
-
> brother ©
> О_о интересно посмотреть на скрипт)
Да это у меня не скрипт, а целая большая программа, что-то вроде прокси-сервера или ретранслятора для IP камер. Принимает один поток - отдает множеству клиентов. Для гигабитной сети и 1000 кадров в сек (JPEG) реально передать.
-
> > а даже по HTTP кадров 200 в секунду
? это 200 запросов или типа кэша и аджакса с буфером в 200 кадров?
-
> brother © (16.06.09 04:11) [37]
> это 200 запросов
Нет конечно. Один поток - один запрос. Каждый кадр не запрашивается. Поток бесконечен и выдается клиенту пока тот желает его принимать. Кадры разделены разделителями. Content-type: multipart/x-mixed-replace
-
> Поток бесконечен и выдается клиенту пока тот желает его > принимать. Кадры разделены разделителями. > Content-type: multipart/x-mixed-replace
а, понял
-
Восхищена как всегда
-
> Восхищена как всегда
Аж пароль забыла :)
-
Я думал что я "моняьк" а тут блин такие фишки пишут JPG передать по сети ух! ну и жесть, а PNG чтоне судьба?! или с ним работать тяжело?! По моему 1 кадра в секунду достаточно.
-
> а тут блин такие фишки пишут JPG передать по сети ух! ну > и жесть, а PNG чтоне судьба?!
какая принципиальная разница какой сжатый кадр передавать?
-
у тебя две разные программы: 1) на Socket, но сней проблемы под XP SP3. 2) по УДП. но по УДП, я не смог сделать чтобы картинку передовало кусками. на этом и завис. Если кто знает, может подскажет как картинку кусками передовать?
-
у тебя две разные программы: 1) на Socket, но сней проблемы под XP SP3. 2) по УДП. но по УДП, я не смог сделать чтобы картинку передовало кусками. на этом и завис. Если кто знает, может подскажет как картинку кусками передовать?
-
> olchick (03.06.2009 14:02:11) [11]
Не проехали, пусть теперь женится.
-
> [0] olchick © (02.06.09 23:15)
не с того вы начали.
-
Зачем поднимать такие старые ветки?
|