Конференция "Сети" » управление удаленным рабочим столом
 
  • PascalC (25.11.08 12:22) [0]
    Здравствуйте, хочу написать программу - аналог Radmin, но не знаю, как организовать передачу изображения, точнее знаю - можно делать скрины, сжимать jpg и отсылать, но возможно есть способы для более быстрой передачи.
    Если у кого-нибудь есть исходники на Delphi по подобным задачам, буду за них признателен. В сети находил только на C++ :(
  • Сергей М. © (25.11.08 12:53) [1]

    > хочу написать программу - аналог Radmin


    А зачем ?
    Чем не устраивает куча существующих аналогичных программ, включая RAdmin ?
  • Slym © (25.11.08 12:53) [2]
    PascalC   (25.11.08 12:22)
    более быстрой передачи

    не в передаче дело... а в ресурсоемкости сжатия...
    можно не весь экран передавать а только изменившуюся часть... а что изменилось это другая история
  • Slym © (25.11.08 13:04) [3]
    Ответ на аналогичный вопрос я нашел у себя в "быстрых ответах"
    код приема/передачи скриншота с jpg сжатием... постить?
  • PascalC (25.11.08 13:14) [4]

    > А зачем ?
    > Чем не устраивает куча существующих аналогичных программ,
    >  включая RAdmin ?

    Хочется расширить функционал этой кучи чтоб все в одном, а вообще -люблю изобретать велосипеды :)


    > не в передаче дело... а в ресурсоемкости сжатия...
    > можно не весь экран передавать а только изменившуюся часть.
    > .. а что изменилось это другая история

    Сравнить две картинки, вырезать измененные фрагменты, передать с координатами массив фрагментов? Не слишком большая нагрузка будет на проц?
    И потом, разные кусочки после сжатия и последующей склейки могут исказиться (если использовать jpg)
    Да и алгоритм поиска фрагментов пока не представляю, сколько их делать? а может передавать координаты/цвет каждого измененного пиксела?

    Поэтому и спрашиваю, может у кого исходники на делфях завалялись, которые не жалко?
  • PascalC (25.11.08 13:16) [5]

    > Ответ на аналогичный вопрос я нашел у себя в "быстрых ответах"
    > код приема/передачи скриншота с jpg сжатием... постить?

    Да, пожалуйста, пригодится.
  • Сергей М. © (25.11.08 13:16) [6]

    > Хочется расширить функционал этой кучи чтоб все в одном


    Что еще соббсно надо кроме интерактивного управления столом ?


    > люблю изобретать велосипеды


    Ну эт другой коленкор)
  • Slym © (25.11.08 13:22) [7]
    это сервер:
    program NetScreenServerCon;
    {$apptype console}

    uses
     Windows,SysUtils,Classes,ScktComp,Graphics,Jpeg;

    type
     TSCThread=class(TServerClientThread)
     private
       Bitmap:TBitmap;
       Jpeg:TJpegImage;
     protected
       procedure GrabScreen(Stream:TStream;const ImgSize:TPoint);
       procedure ClientExecute; override;
     public
       constructor Create(CreateSuspended: Boolean; ASocket: TServerClientWinSocket);
       destructor Destroy; override;
     end;

    constructor TSCThread.Create(CreateSuspended: Boolean;
     ASocket: TServerClientWinSocket);
    begin
     Bitmap:=TBitmap.Create;
     Jpeg:=TJpegImage.Create;
     inherited;
    end;

    destructor TSCThread.Destroy;
    begin
     Jpeg.Free;
     Bitmap.Free;
     inherited;
    end;

    procedure TSCThread.GrabScreen(Stream:TStream;const ImgSize:TPoint);
    var
     Desktop:HWnd;
     DesktopRect: TRect;
     DesktopDC:HDc;
    begin
     Stream.Size:=0;
     Desktop:=GetDesktopWindow;
     GetWindowRect(Desktop,DesktopRect);
     Bitmap.Height:=ImgSize.Y;
     Bitmap.Width:=ImgSize.X;
     DesktopDC:=GetWindowDC(Desktop);
     try
       Win32Check(StretchBlt(Bitmap.Canvas.Handle,0,0,Bitmap.Width,Bitmap.Height,
                 DesktopDC,DesktopRect.Left,DesktopRect.Top,DesktopRect.Right,DesktopRect.Bottom, SRCCOPY));
     finally
       ReleaseDC(Desktop,DesktopDC);
     end;
     Jpeg.Assign(Bitmap);
     Jpeg.SaveToStream(Stream);
    end;

    procedure TSCThread.ClientExecute;
    var
     ScreenStream:TMemoryStream;
     Buf:array[0..1023] of byte;
     ImgSize:TPoint;
     size:integer;
    begin
     while (not Terminated) and ClientSocket.Connected do
     try
       ScreenStream:=TMemoryStream.Create;
       try
         if ClientSocket.ReceiveBuf(ImgSize,SizeOf(ImgSize))<>SizeOf(ImgSize) then exit;
         GrabScreen(ScreenStream,ImgSize);
         ScreenStream.Position:=0;
         size:=ScreenStream.Size;
         ClientSocket.SendBuf(size,SizeOf(size));
         while ScreenStream.Position<ScreenStream.Size do
         begin
           size:=ScreenStream.Read(Buf,SizeOf(Buf));
           if ClientSocket.SendBuf(Buf,size)<>size then exit;
         end;
       finally
         ScreenStream.Free;
       end;
     except
       Terminate;
       HandleException;
     end;
    end;

    function Proc2Method(Code,Data:pointer):TMethod;
    begin
     result.Code:=Code;
     result.Data:=Data;
    end;

    procedure GetThread(self,Sender: TObject; ClientSocket: TServerClientWinSocket;
       var SocketThread: TServerClientThread);
    begin
     SocketThread:=TSCThread.Create(true,ClientSocket);
     SocketThread.Priority:=tpLower;
     SocketThread.Resume;
    end;

    var Server:TServerSocket;

    begin
     Server:=TServerSocket.Create(nil);
     try
       Server.ServerType:=stThreadBlocking;
       Server.OnGetThread:=TGetThreadEvent(Proc2Method(@GetThread,Server));
       Server.Port:=1234;
       Server.Active:=true;
       while Server.Active do Sleep(100);
     finally
       Server.Free;
     end;
    end.

  • Slym © (25.11.08 13:24) [8]
    это клиент:
    unit ClientUnit;

    interface

    uses
     Windows, Messages, SysUtils, Classes, Graphics, Forms,
     ExtCtrls, StdCtrls, ScktComp, Controls;

    type
     TClientThread=class(TThread)
     private
       ClientSocket: TClientSocket;
       LastUpdate:DWORD;
       Bitmap:TBitmap;
     protected
       procedure UpdateScreen;
       procedure Execute;override;
     public
       constructor Create(CreateSuspended: Boolean;const Address:string);
       destructor Destroy;override;
     end;

     TForm1 = class(TForm)
       Panel1: TPanel;
       AddressEd: TEdit;
       Button1: TButton;
       Image: TImage;
       procedure Button1Click(Sender: TObject);
     private
       ClientThread:TClientThread;
     public
     end;

    var
     Form1: TForm1;

    implementation
    uses math,Jpeg;
    {$R *.dfm}

    { TClientThread }

    constructor TClientThread.Create(CreateSuspended: Boolean;const Address:string);
    var i:integer;
    begin
     Bitmap:=TBitmap.Create;
     ClientSocket:=TClientSocket.Create(nil);
     ClientSocket.ClientType:=ctBlocking;
     i:=pos(':',Address);
     ClientSocket.Address:=copy(Address,1,i-1);
     ClientSocket.Port:=StrToInt(copy(Address,i+1,MaxInt));
     ClientSocket.Active:=true;
     inherited Create(CreateSuspended);
    end;

    destructor TClientThread.Destroy;
    begin
     ClientSocket.Free;
     Bitmap.Free;
     inherited;
    end;

    procedure TClientThread.Execute;
    var
     Socket:TClientWinSocket;
     ScreenStream:TMemoryStream;
     ImgSize:TPoint;
     Buf:array[0..1023] of byte;
     size,ToRead:integer;
     Jpeg:TJpegImage;
    begin
     Socket:=ClientSocket.Socket;
     try
       ScreenStream:=TMemoryStream.Create;
       try
         while Socket.Connected do
         begin
           ImgSize.X:=Form1.Image.Width;
           ImgSize.Y:=Form1.Image.Height;
           if Socket.SendBuf(ImgSize,SizeOf(ImgSize))<>SizeOf(ImgSize) then exit;
           if Socket.ReceiveBuf(size,SizeOf(size))<>4 then exit;
           if (Size<0) or (Size>maxInt-1) then exit;
           ScreenStream.Size:=Size;
           ScreenStream.Position:=0;
           ToRead:=ScreenStream.Size-ScreenStream.Position;
           ToRead:=Min(ToRead,Length(Buf));
           while (ToRead>0) and Socket.Connected do
           begin
             Size:=Socket.ReceiveBuf(Buf,ToRead);
             if Size<0 then exit;
             ScreenStream.WriteBuffer(Buf,Size);
             ToRead:=ScreenStream.Size-ScreenStream.Position;
             ToRead:=Min(ToRead,Length(Buf));
           end;
           ScreenStream.Position:=0;
           Jpeg:=TJpegImage.Create;
           try
             Jpeg.LoadFromStream(ScreenStream);
             Bitmap.Assign(Jpeg);
           finally
             Jpeg.Free;
           end;
           Synchronize(UpdateScreen);
         end;
       finally
         ScreenStream.Free;
       end;
     finally
       Socket.Close;
     end;
    end;

    procedure TClientThread.UpdateScreen;
    var tick:DWORD;
    begin
     Form1.Image.Picture.Bitmap.Assign(Bitmap);
     tick:=GetTickCount;
     Form1.Image.Canvas.Brush.Style:=bsClear;
     Form1.Image.Canvas.TextOut(1,1,Format('Разрешение: %d:%d, cкорость: %f кадр/сек',[Bitmap.Width,Bitmap.Height,1000/(tick-LastUpdate)]));
     LastUpdate:=tick;
    end;

    procedure TForm1.Button1Click(Sender: TObject);
    begin
     ClientThread:=TClientThread.Create(true,AddressEd.Text);
     ClientThread.FreeOnTerminate:=true;
     ClientThread.Priority:=tpLower;
     ClientThread.Resume;
    end;

    end.

  • DVM © (25.11.08 13:26) [9]
    сжимать в Jpeg лучше с помощью Intel Jpeg Library. Она в разы быстрее.
  • PascalC (25.11.08 13:27) [10]
    спасибо
  • Slym © (25.11.08 14:29) [11]
    переписал под Intel Jpeg Library стало быстрее раза в два-три
  • HITMAN (12.02.09 21:17) [12]
    Всё работает отлично!!!
    Не сталкивался с консольными приложениями, подскажите, что нужно дописать, чтобы консоль сервера исчезала\пряталась?
  • Slym © (13.02.09 04:33) [13]
    HITMAN   (12.02.09 21:17) [12]
    {$apptype console}

    УБЕРИ :)
  • kvorubin © (13.02.09 20:02) [14]
    Благодарю!
    (пора заняться юзаньем консольных программ :)
  • ikot © (01.06.09 11:40) [15]

    > переписал под Intel Jpeg Library стало быстрее раза в два-
    > три


    а как пользоваться этой библиотекой. Можешь выложить исходник?
  • CrytoGen (01.06.09 14:22) [16]
  • olchick © (03.06.09 12:23) [17]

    > это клиент:unit ClientUnit;interfaceuses  Windows, Messages,
    >  SysUtils, Classes, Graphics, Forms,  ExtCtrls, StdCtrls,
    >  ScktComp, Controls;type  TClientThread=class(TThread)  private
    >    ClientSocket: TClientSocket;    LastUpdate:DWORD;    Bitmap:
    > TBitmap;  protected    procedure UpdateScreen;    procedure
    > Execute;override;  public    constructor Create(CreateSuspended:
    >  Boolean;const Address:string);    destructor Destroy;override;
    >   end;  TForm1 = class(TForm)    Panel1: TPanel;    AddressEd:
    >  TEdit;    Button1: TButton;    Image: TImage;    procedure
    > Button1Click(Sender: TObject);  private    ClientThread:
    > TClientThread;  public  end;var  Form1: TForm1;implementationuses
    > math,Jpeg;{$R *.dfm}{ TClientThread }constructor TClientThread.
    > Create(CreateSuspended: Boolean;const Address:string);var
    > i:integer;begin  Bitmap:=TBitmap.Create;  ClientSocket:=TClientSocket.
    > Create(nil);  ClientSocket.ClientType:=ctBlocking;  i:=pos(':
    > ',Address);  ClientSocket.Address:=copy(Address,1,i-1);
    >  ClientSocket.Port:=StrToInt(copy(Address,i+1,MaxInt));
    >  ClientSocket.Active:=true;  inherited Create(CreateSuspended);
    > end;destructor TClientThread.Destroy;begin  ClientSocket.
    > Free;  Bitmap.Free;  inherited;end;procedure TClientThread.
    > Execute;var  Socket:TClientWinSocket;  ScreenStream:TMemoryStream;
    >   ImgSize:TPoint;  Buf:array[0..1023] of byte;  size,ToRead:
    > integer;  Jpeg:TJpegImage;begin  Socket:=ClientSocket.Socket;
    >   try    ScreenStream:=TMemoryStream.Create;    try    
    >  while Socket.Connected do      begin        ImgSize.X:=Form1.
    > Image.Width;        ImgSize.Y:=Form1.Image.Height;      
    >  if Socket.SendBuf(ImgSize,SizeOf(ImgSize))<>SizeOf(ImgSize)
    > then exit;        if Socket.ReceiveBuf(size,SizeOf(size))<>4
    > then exit;        if (Size<0) or (Size>maxInt-1) then exit;
    >         ScreenStream.Size:=Size;        ScreenStream.Position:
    > =0;        ToRead:=ScreenStream.Size-ScreenStream.Position;
    >         ToRead:=Min(ToRead,Length(Buf));        while (ToRead>0)
    > and Socket.Connected do        begin          Size:=Socket.
    > ReceiveBuf(Buf,ToRead);          if Size<0 then exit;  
    >        ScreenStream.WriteBuffer(Buf,Size);          ToRead:
    > =ScreenStream.Size-ScreenStream.Position;          ToRead:
    > =Min(ToRead,Length(Buf));        end;        ScreenStream.
    > Position:=0;        Jpeg:=TJpegImage.Create;        try
    >          Jpeg.LoadFromStream(ScreenStream);          Bitmap.
    > Assign(Jpeg);        finally          Jpeg.Free;        end;
    >         Synchronize(UpdateScreen);      end;    finally
    >      ScreenStream.Free;    end;  finally    Socket.Close;
    >   end;end;procedure TClientThread.UpdateScreen;var tick:
    > DWORD;begin  Form1.Image.Picture.Bitmap.Assign(Bitmap);
    >  tick:=GetTickCount;  Form1.Image.Canvas.Brush.Style:=bsClear;
    >   Form1.Image.Canvas.TextOut(1,1,Format('Разрешение: %d:
    > %d, cкорость: %f кадр/сек',[Bitmap.Width,Bitmap.Height,1000/(tick-
    > LastUpdate)]));  LastUpdate:=tick;end;procedure TForm1.Button1Click(Sender:
    >  TObject);begin  ClientThread:=TClientThread.Create(true,
    > AddressEd.Text);  ClientThread.FreeOnTerminate:=true;  ClientThread.
    > Priority:=tpLower;  ClientThread.Resume;end;end.


    в каком формате здесь вводится адресс машины 127:0:0:1 или другом?
  • olchick © (03.06.09 12:32) [18]
    все поняла... извините за глупый вопрос
  • DVM © (04.06.09 15:17) [19]

    > olchick ©   (03.06.09 12:23) [17]
    >
    >


    > в каком формате здесь вводится адресс машины 127:0:0:1 или
    > другом?

    Издеваетесь?
 
Конференция "Сети" » управление удаленным рабочим столом
Есть новые Нет новых   [134436   +23][b:0][p:0.004]