Solved

JPEG transmission in Ethernet

Posted on 1998-12-03
21
283 Views
Last Modified: 2010-04-04
I'd like to develop a Software which is able to view the content of one Screen on all others in a network.
I know how to take a screenshot and I can compress it with JPEG (takes too much time) but how do I
transmit it in a fast way without using a network drive ? (Delphi 3 Standard)
0
Comment
Question by:ItsMe
  • 11
  • 10
21 Comments
 

Author Comment

by:ItsMe
Comment Utility
Edited text of question
0
 
LVL 3

Accepted Solution

by:
williams2 earned 100 total points
Comment Utility
Ok "ItsMe" I've got your answer right here. I'm not using any compression, that's up to you, but this works:

You need two projects. In both you need to activate the FormCreate event before pasting the following lines. The rest is done automatically:

Server part:
unit Unit1;

interface

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

Const
  //You may set this to False if you would like the whole image!
  STRETCH = True;
  STRETCH_WIDTH = 200;
  STRETCH_HEIGHT = 150;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    ServerSocket1: TServerSocket;
    procedure ServerSocket1ClientRead(Sender: TObject;
      Socket: TCustomWinSocket);
  private
    { Private declarations }
    Stream: TMemoryStream;
    procedure SendNextPart(Socket: TCustomWinSocket);
  public
    { Public declarations }
    Timer: TTimer;
    procedure OnTime(Sender: TObject);
    procedure SendScreen(Socket: TCustomWinSocket);
  protected
    Bitmap: TBitmap;
  end;

var
  Form1: TForm1;


implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
  Bitmap:= TBitmap.Create;
  if STRETCH then
  begin
    Bitmap.Width:= STRETCH_WIDTH;
    Bitmap.height:= STRETCH_HEIGHT;
  End else
  begin
    Bitmap.Width:= Screen.Width;
    Bitmap.Height:= Screen.Height;
  End;
  Timer:= TTimer.Create(Self);
  Timer.Interval:= 1000;
  Timer.OnTimer:= OnTime;
  Timer.Enabled:= True;
  ServerSocket1:= TServerSocket.Create(Self);
  With ServerSocket1 do
  begin
    Port:= 2500;
    Active:= True;
    ServerType:= stNonBlocking;
    OnClientRead:= ServerSocket1ClientRead;
  End;
  Stream:= TMemoryStream.Create;
end;

procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var
  S: String;
Begin
  S:= Socket.ReceiveText;
  If S='Get me the screen' then SendScreen(Socket) else
  If S='Send next' then SendNextPart(Socket) else
  If S='Done' then Socket.Close;
End;

procedure TForm1.SendScreen(Socket: TCustomWinSocket);
var
  Size: Integer;
Begin
  Bitmap.SaveToStream(Stream);
  Size:= Stream.Size;
  Stream.Position:= 0;
  Socket.SendBuf(Size,SizeOf(Size));
End;

procedure TForm1.SendNextPart(Socket: TCustomWinSocket);
const
  MaxChunkSize = 8192; { copy in 8K chunks }
var
  ChunkSize: Integer;
  CopyBuffer: Array[0..MaxChunkSize] of Byte;
Begin
  Chunksize:= Stream.Size-Stream.Position;
  If ChunkSize>0 then
  begin
    If ChunkSize > MaxChunkSize then ChunkSize:= MaxChunkSize;
    Stream.Read(CopyBuffer,ChunkSize);
    Socket.SendBuf(CopyBuffer,ChunkSize);
  End else
    Stream.Clear; //The final
End;

procedure TForm1.OnTime(Sender: TObject);
var
  dwRop: DWord;
  DC: hDC;
begin
  dwRop:= SRCCOPY;
  DC:= GetDC(0);
  If STRETCH then
    StretchBlt(
      Bitmap.Canvas.Handle, // handle to destination device context
      0, // x-coordinate of destination rectangle's upper-left corner
      0, // y-coordinate of destination rectangle's upper-left corner
      Bitmap.Width, // width of destination rectangle
      Bitmap.Height, // height of destination rectangle
      DC, // handle to source device context
      0, // x-coordinate of source rectangle's upper-left corner
      0, // y-coordinate of source rectangle's upper-left corner
      Screen.Width,      // width of source rectangle
      Screen.Height,      // height of source rectangle
      dwRop        // raster operation code (See below)
    )
  else
    BitBlt(
      Bitmap.Canvas.Handle, // handle to destination device context
      0, // x-coordinate of destination rectangle's upper-left corner
      0, // y-coordinate of destination rectangle's upper-left corner
      Bitmap.Width, // width of destination rectangle
      Bitmap.Height, // height of destination rectangle
      DC, // handle to source device context
      0, // x-coordinate of source rectangle's upper-left corner
      0, // y-coordinate of source rectangle's upper-left corner
      dwRop        // raster operation code (See below)
    );
  ReleaseDC(0,DC)
{
BLACKNESS Fills the destination rectangle using the color associated with
index 0 in the physical palette. (This color is black for the
                default physical palette.)
DSTINVERT Inverts the destination rectangle.
MERGECOPY Merges the colors of the source rectangle with the specified
pattern by using the Boolean AND operator.
MERGEPAINT Merges the colors of the inverted source rectangle with the
colors of the destination rectangle by using the Boolean OR
                operator.
NOTSRCCOPY Copies the inverted source rectangle to the destination.
NOTSRCERASE Combines the colors of the source and destination rectangles
by using the Boolean OR operator and then inverts the resultant
                color.
PATCOPY Copies the specified pattern into the destination bitmap.
PATINVERT Combines the colors of the specified pattern with the colors of
the destination rectangle by using the Boolean XOR operator.
PATPAINT Combines the colors of the pattern with the colors of the
inverted source rectangle by using the Boolean OR operator. The
                result of this operation is combined with the colors of the
                destination rectangle by using the Boolean OR operator.
SRCAND Combines the colors of the source and destination rectangles
by using the Boolean AND operator.
SRCCOPY Copies the source rectangle directly to the destination
rectangle.
SRCERASE Combines the inverted colors of the destination rectangle with
the colors of the source rectangle by using the Boolean AND operator.
SRCINVERT Combines the colors of the source and destination rectangles
by using the Boolean XOR operator.
SRCPAINT Combines the colors of the source and destination rectangles by
using the Boolean OR operator.
WHITENESS Fills the destination rectangle using the color associated with
index 1 in the physical palette. (This color is white for the
                default physical palette.)
}
End;

end.






ClientPart:
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    ProgressBar: TProgressBar;
    Button1: TButton;
    Button2: TButton;
    ClientSocket1: TClientSocket;
    Image1: TImage;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure ClientSocket1Connect(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ClientSocket1Error(Sender: TObject; Socket: TCustomWinSocket;
      ErrorEvent: TErrorEvent; var ErrorCode: Integer);
    procedure Button2Click(Sender: TObject);
    procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
    procedure ClientSocket1Disconnect(Sender: TObject;
      Socket: TCustomWinSocket);

  private
    Stream: TMemoryStream;
  public
    Procedure UpdateProgressBar;
  protected
    Bitmap: TBitmap;
    Receiving: Boolean;
    FSize: Integer;
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
begin
  Label1.Caption:= 'Connecting..';
  ClientSocket1.Open;
end;

procedure TForm1.ClientSocket1Connect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
  Label1.Caption:= 'Connected';
  Receiving:= False;
  FSize:= 0;
end;

procedure TForm1.ClientSocket1Error(Sender: TObject;
  Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
  var ErrorCode: Integer);
begin
  ShowMessage('Did you startup the server? I cannot find it!');
end;


procedure TForm1.Button2Click(Sender: TObject);
begin
  if ClientSocket1.Active then
    ClientSocket1.Socket.SendText('Get me the screen');
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Label1:= TLabel.Create(Self);
  Label1.SetBounds(32,72,32,13);
  Label1.Parent:= Self;
  Label1.Caption:= 'Idle..';
  Button1:= TButton.Create(Self);
  Button1.SetBounds(8,8,75,25);
  Button1.Parent:= Self;
  Button1.Caption:= 'Connect';
  Button1.OnClick:= Button1Click;
  Button2:= TButton.Create(Self);
  Button2.SetBounds(8,40,75,25);
  Button2.Parent:= Self;
  Button2.Caption:= 'Get screen';
  Button2.OnClick:= Button2Click;
  ClientSocket1:= TClientSocket.Create(Self);
  With ClientSocket1 do
  begin
    Active := False;
    ClientType := ctNonBlocking;
    Port := 2500;
    Address := '127.0.0.1';
    OnConnect := ClientSocket1Connect;
    OnDisconnect := ClientSocket1Disconnect;
    OnRead := ClientSocket1Read;
    OnError := ClientSocket1Error;
  end;
  Image1:= TImage.Create(Self);
  Image1.SetBounds(100,0,0,0);
  Image1.AutoSize:= true;
  Image1.Parent:= Self;

  Stream:= TMemoryStream.Create;
  ProgressBar:= TProgressBar.Create(Self);
  ProgressBar.Min:= 0;
  ProgressBar.Align:= alBottom;
  ProgressBar.Parent:= Self;
end;

Procedure TForm1.UpdateprogressBar;
Begin
  ProgressBar.Position:= ProgressBar.Max-FSize;
  progressBar.Update;
End;

procedure TForm1.ClientSocket1Read(Sender: TObject;
  Socket: TCustomWinSocket);
const
  MaxChunkSize = 8192; { copy in 8K chunks }
var
  BytesReceived: Longint;
  CopyBuffer: Array[0..MaxChunkSize] of Byte; { buffer for copying }
  ChunkSize: Integer;
  TempSize: Integer;
begin
  If FSize=0 then
  begin
    If Socket.ReceiveLength>=SizeOf(TempSize) then
    begin
      Socket.ReceiveBuf(TempSize,SizeOf(TempSize)); //get the size
      Stream.SetSize(TempSize);
      Stream.Position:= 0;
      ProgressBar.Max:= TempSize;
      FSize:= TempSize; //Threadsafe code!
    End;
  End;
  If (FSize>0) and not(Receiving) then
  begin
    Receiving:= True;
    While Socket.ReceiveLength>0 do
    Begin
      ChunkSize:= Socket.ReceiveLength;
      If ChunkSize > MaxChunkSize then ChunkSize:= MaxChunkSize;
      BytesReceived:= Socket.ReceiveBuf(CopyBuffer,ChunkSize);
      Stream.Write(CopyBuffer, BytesReceived); { ...write chunk }
      Dec(FSize,BytesReceived);
      UpdateProgressBar;
    End;
    //This is called "to Syncronize trasnsmissions"
    Socket.SendText('Send next');
    If FSize=0 then
    begin
      Socket.SendText('Done');
      Stream.Position:= 0;
      Image1.Picture.Bitmap.LoadFromStream(Stream);
      FSize:= 0;
      ProgressBar.Position:= 0;
//      Stream.SetSize(0);
      Stream.Clear;
    End;
    Receiving:= False;
  End;
end;


procedure TForm1.ClientSocket1Disconnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
  Label1.Caption:= 'Disconnected';
end;

end.
0
 

Author Comment

by:ItsMe
Comment Utility
Dear williams2,
I guess that your program will work beautifully. I wasn't able to test it because my compiler couldn't
find the ScktComp.dcu. Why this ?
0
 
LVL 3

Expert Comment

by:williams2
Comment Utility
Haven't you got the C/S version of Delphi 2/3? If not, I will have to provide some freeware socket-components (TCP/IP transmission) ..If so, I may have to look once more at the code, and change these components (TClientSocket and TServerSocket) with some free ones.

I'll go look up some suitable components for you now, so I'll be back to you. Basically they all work and act the same way, so that should not be a problem.

Regards
Williams
0
 

Author Comment

by:ItsMe
Comment Utility
I've already downloaded Francois Piettes TWinSocket Component. You can find it on the Delphi Super Page.
Perhaps your program works with that, too ? Another Question: Does this program works with Novell ?
0
 
LVL 3

Expert Comment

by:williams2
Comment Utility
Yes it does, I have testet this on Novell workstations, connecting from one to another. Of cause it needs the workstations to have the TCP/IP protocol installed in their network configurations, but yes, it works!

I will now change the program to use Francois Piettes winsock components, I just need a little time to fix this!

See you later

Cheers
Williams
0
 

Author Comment

by:ItsMe
Comment Utility
Does it work only with 2 PC's or with more, too ?
0
 

Author Comment

by:ItsMe
Comment Utility
Hi Williams ! Did you find out, how it works with TWSocket ?
0
 
LVL 3

Expert Comment

by:williams2
Comment Utility
Sorry ItsMe! ..I have been on a weekend with my friends, and when I was about to tell people, my modem got ****ed up. So I have switched it here today :-((( ..But everything is possible, and I'm 100% convinced, that I will solve this problem with or wihtout F.Piettes components; I know some friends who has made them work fairly good! ..But I'll solve your problem, trust me!

Cheers
Williams
0
 

Author Comment

by:ItsMe
Comment Utility
OK that's very fine.
cu
Philip
0
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

 
LVL 3

Expert Comment

by:williams2
Comment Utility
I really needed to make an example using F.Piettes components. He actually makes it a lot cheaper developing client/server applications, due to the price of a Delphi C/S developer license.

But here you go. You should replace the contents of the existing example:

Server:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls, StdCtrls, ExtDlgs, WSocket, Winsock;

Const
  //You may set this to False if you would like the whole image!
  STRETCH = True;
  STRETCH_WIDTH = 200;
  STRETCH_HEIGHT = 150;

type
  TForm1 = class(TForm)
    WSocket1: TWSocket;
    procedure FormCreate(Sender: TObject);
  private
//    ServerSocket1: TServerSocket;
    SrvSocket,
    CliSocket: TWSocket;
//    procedure ServerSocket1ClientRead(Sender: TObject;
//      Socket: TCustomWinSocket);
    procedure SrvSocketSessionAvailable(Sender: TObject; Error: Word);
    procedure SocketDataAvailable(Sender: TObject; Error: Word);
  private
    { Private declarations }
    Stream: TMemoryStream;
//    procedure SendNextPart(Socket: TCustomWinSocket);
    procedure SendNextPart(Socket: TWSocket);
  public
    { Public declarations }
    Timer: TTimer;
    procedure OnTime(Sender: TObject);
//    procedure SendScreen(Socket: TCustomWinSocket);
    procedure SendScreen(Socket: TWSocket);
  protected
    Bitmap: TBitmap;
  end;

var
  Form1: TForm1;


implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
  Bitmap:= TBitmap.Create;
  if STRETCH then
  begin
    Bitmap.Width:= STRETCH_WIDTH;
    Bitmap.height:= STRETCH_HEIGHT;
  End else
  begin
    Bitmap.Width:= Screen.Width;
    Bitmap.Height:= Screen.Height;
  End;
  Timer:= TTimer.Create(Self);
  Timer.Interval:= 1000;
  Timer.OnTimer:= OnTime;
  Timer.Enabled:= True;
{  ServerSocket1:= TServerSocket.Create(Self);
  With ServerSocket1 do
  begin
    Port:= 2500;
    Active:= True;
    ServerType:= stNonBlocking;
    OnClientRead:= ServerSocket1ClientRead;
  End;}
  CliSocket:= TWSocket.Create(self);
  CliSocket.OnDataAvailable:= SocketDataAvailable;
  SrvSocket:= TWSocket.Create(Self);
  With SrvSocket do
  begin
    Addr              := '127.0.0.1';      { Accept local clients }
    Port              := '2500';
    OnSessionAvailable:= SrvSocketSessionAvailable;
    Listen;                                { Start listening for client }
  End;
  Stream:= TMemoryStream.Create;
end;

procedure TForm1.SrvSocketSessionAvailable(Sender: TObject; Error: Word);
var
    NewHSocket : TSocket;
begin
    { We need to accept the client connection }
    NewHSocket := SrvSocket.Accept;

    { And then associate this connection with our client socket }
    CliSocket.Dup(NewHSocket);
end;

procedure TForm1.SocketDataAvailable(Sender: TObject; Error: Word);
//procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
//  Socket: TCustomWinSocket);
var
  S: String;
  Socket: TWSocket;
Begin
  Socket:= TWSocket(Sender);
//  S:= Socket.ReceiveText;
  S:= Socket.ReceiveStr;
  If S='Get me the screen' then SendScreen(Socket) else
  If S='Send next' then SendNextPart(Socket) else
  If S='Done' then Socket.Close;
End;

//procedure TForm1.SendScreen(Socket: TCustomWinSocket);
procedure TForm1.SendScreen(Socket: TWSocket);
var
  Size: Integer;
Begin
  Bitmap.SaveToStream(Stream);
  Size:= Stream.Size;
  Stream.Position:= 0;
//  Socket.SendBuf(Size,SizeOf(Size));
  Socket.Send(@Size,SizeOf(Size));
End;

//procedure TForm1.SendNextPart(Socket: TCustomWinSocket);
procedure TForm1.SendNextPart(Socket: TWSocket);
const
  MaxChunkSize = 8192; { copy in 8K chunks }
var
  ChunkSize: Integer;
  CopyBuffer: Array[0..MaxChunkSize] of Byte;
Begin
  Chunksize:= Stream.Size-Stream.Position;
  If ChunkSize>0 then
  begin
    If ChunkSize > MaxChunkSize then ChunkSize:= MaxChunkSize;
    Stream.Read(CopyBuffer,ChunkSize);
    Socket.Send(@CopyBuffer,ChunkSize);
//    Socket.SendBuf(CopyBuffer,ChunkSize);
  End else
    Stream.Clear; //The final
End;

procedure TForm1.OnTime(Sender: TObject);
var
  dwRop: DWord;
  DC: hDC;
begin
  dwRop:= SRCCOPY;
  DC:= GetDC(0);
  If STRETCH then
    StretchBlt(
      Bitmap.Canvas.Handle, // handle to destination device context
      0, // x-coordinate of destination rectangle's upper-left corner
      0, // y-coordinate of destination rectangle's upper-left corner
      Bitmap.Width, // width of destination rectangle
      Bitmap.Height, // height of destination rectangle
      DC, // handle to source device context
      0, // x-coordinate of source rectangle's upper-left corner
      0, // y-coordinate of source rectangle's upper-left corner
      Screen.Width,      // width of source rectangle
      Screen.Height,      // height of source rectangle
      dwRop        // raster operation code (See below)
    )
  else
    BitBlt(
      Bitmap.Canvas.Handle, // handle to destination device context
      0, // x-coordinate of destination rectangle's upper-left corner
      0, // y-coordinate of destination rectangle's upper-left corner
      Bitmap.Width, // width of destination rectangle
      Bitmap.Height, // height of destination rectangle
      DC, // handle to source device context
      0, // x-coordinate of source rectangle's upper-left corner
      0, // y-coordinate of source rectangle's upper-left corner
      dwRop        // raster operation code (See below)
    );
  ReleaseDC(0,DC)
{
BLACKNESS Fills the destination rectangle using the color associated with
index 0 in the physical palette. (This color is black for the
                default physical palette.)
DSTINVERT Inverts the destination rectangle.
MERGECOPY Merges the colors of the source rectangle with the specified
pattern by using the Boolean AND operator.
MERGEPAINT Merges the colors of the inverted source rectangle with the
colors of the destination rectangle by using the Boolean OR
                operator.
NOTSRCCOPY Copies the inverted source rectangle to the destination.
NOTSRCERASE Combines the colors of the source and destination rectangles
by using the Boolean OR operator and then inverts the resultant
                color.
PATCOPY Copies the specified pattern into the destination bitmap.
PATINVERT Combines the colors of the specified pattern with the colors of
the destination rectangle by using the Boolean XOR operator.
PATPAINT Combines the colors of the pattern with the colors of the
inverted source rectangle by using the Boolean OR operator. The
                result of this operation is combined with the colors of the
                destination rectangle by using the Boolean OR operator.
SRCAND Combines the colors of the source and destination rectangles
by using the Boolean AND operator.
SRCCOPY Copies the source rectangle directly to the destination
rectangle.
SRCERASE Combines the inverted colors of the destination rectangle with
the colors of the source rectangle by using the Boolean AND operator.
SRCINVERT Combines the colors of the source and destination rectangles
by using the Boolean XOR operator.
SRCPAINT Combines the colors of the source and destination rectangles by
using the Boolean OR operator.
WHITENESS Fills the destination rectangle using the color associated with
index 1 in the physical palette. (This color is white for the
                default physical palette.)
}
End;

end.


Client:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls, ComCtrls, WSocket;

type
  TForm1 = class(TForm)
    WSocket1: TWSocket;
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    ProgressBar: TProgressBar;
    Button1: TButton;
    Button2: TButton;
//    ClientSocket1: TClientSocket;
    Image1: TImage;
    Label1: TLabel;
    CliSocket: TWSocket;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
{    procedure ClientSocket1Connect(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ClientSocket1Error(Sender: TObject; Socket: TCustomWinSocket;
      ErrorEvent: TErrorEvent; var ErrorCode: Integer);
    procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
    procedure ClientSocket1Disconnect(Sender: TObject;
      Socket: TCustomWinSocket);}
    procedure CliSocketSessionConnected(Sender: TObject; Error: Word);
    procedure CliSocketSessionClosed(Sender: TObject; Error: Word);
    procedure CliSocketDataAvailable(Sender: TObject; Error: Word);
    procedure CliSocketError(Sender: TObject);
  private
    Stream: TMemoryStream;
  public
    Procedure UpdateProgressBar;
  protected
    Bitmap: TBitmap;
    Receiving: Boolean;
    FSize: Integer;
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
begin
  Label1.Caption:= 'Connecting..';
//  ClientSocket1.Open;
  CliSocket.Addr   := 'localhost';        { Server host name              }
  CliSocket.Proto  := 'tcp';              { Protocol we wants to use      }
  CliSocket.Port   := '2500';             { The port we wants to connect  }
  CliSocket.Connect;                      { Let's connect !               }
  { Connect is just a request, it returns immediately. We eventually gets }
  { gets connected later. At that time we will receive the event          }
  { SessionConnected. If you need a timeout, you have to start a TTimer.  }
end;

//procedure TForm1.ClientSocket1Connect(Sender: TObject;
//  Socket: TCustomWinSocket);
procedure TForm1.CliSocketSessionConnected(Sender: TObject; Error: Word);
begin
  Label1.Caption:= 'Connected';
  Receiving:= False;
  FSize:= 0;
end;

//procedure TForm1.ClientSocket1Error(Sender: TObject;
//  Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
//  var ErrorCode: Integer);
procedure TForm1.CliSocketError(Sender: TObject);
begin
  ShowMessage('Did you startup the server? I cannot find it!');
end;


procedure TForm1.Button2Click(Sender: TObject);
begin
//  if ClientSocket1.Active then
//    ClientSocket1.Socket.SendText('Get me the screen');
  CliSocket.SendStr('Get me the screen');
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Label1:= TLabel.Create(Self);
  Label1.SetBounds(32,72,32,13);
  Label1.Parent:= Self;
  Label1.Caption:= 'Idle..';
  Button1:= TButton.Create(Self);
  Button1.SetBounds(8,8,75,25);
  Button1.Parent:= Self;
  Button1.Caption:= 'Connect';
  Button1.OnClick:= Button1Click;
  Button2:= TButton.Create(Self);
  Button2.SetBounds(8,40,75,25);
  Button2.Parent:= Self;
  Button2.Caption:= 'Get screen';
  Button2.OnClick:= Button2Click;
{  ClientSocket1:= TClientSocket.Create(Self);
  With ClientSocket1 do
  begin
    Active := False;
    ClientType := ctNonBlocking;
    Port := 2500;
    Address := '127.0.0.1';
    OnConnect := ClientSocket1Connect;
    OnDisconnect := ClientSocket1Disconnect;
    OnRead := ClientSocket1Read;
    OnError := ClientSocket1Error;
  end;}
  CliSocket:= TWSocket.Create(Self);
  With CliSocket do
  begin
    OnSessionConnected:= CliSocketSessionConnected;
    OnSessionClosed:= CliSocketSessionClosed;
    OnDataAvailable:= CliSocketDataAvailable;
    OnError:= CliSocketError;
  //  CliSocket.
  End;
  Image1:= TImage.Create(Self);
  Image1.SetBounds(100,0,0,0);
  Image1.AutoSize:= true;
  Image1.Parent:= Self;

  Stream:= TMemoryStream.Create;
  ProgressBar:= TProgressBar.Create(Self);
  ProgressBar.Min:= 0;
  ProgressBar.Align:= alBottom;
  ProgressBar.Parent:= Self;
end;

Procedure TForm1.UpdateprogressBar;
Begin
  ProgressBar.Position:= ProgressBar.Max-FSize;
  progressBar.Update;
End;

//procedure TForm1.ClientSocket1Read(Sender: TObject;
//  Socket: TCustomWinSocket);
procedure TForm1.CliSocketDataAvailable(Sender: TObject; Error: Word);
const
  MaxChunkSize = 8192; { copy in 8K chunks }
var
  BytesReceived: Longint;
  CopyBuffer: Array[0..MaxChunkSize] of Byte; { buffer for copying }
  ChunkSize: Integer;
  TempSize: Integer;
begin
  If FSize=0 then
  begin
//    If Socket.ReceiveLength>=SizeOf(TempSize) then
    If CliSocket.RcvdCount>=SizeOf(TempSize) then
    begin
//      Socket.ReceiveBuf(TempSize,SizeOf(TempSize)); //get the size
      CliSocket.Receive(@TempSize,SizeOf(TempSize));
//      Socket.ReceiveBuf(TempSize,SizeOf(TempSize)); //get the size
      Stream.SetSize(TempSize);
      Stream.Position:= 0;
      ProgressBar.Max:= TempSize;
      FSize:= TempSize; //Threadsafe code!
    End;
  End;
  If (FSize>0) and not(Receiving) then
  begin
    Receiving:= True;
//    While Socket.ReceiveLength>0 do
    While CliSocket.RcvdCount>0 do
    Begin
//      ChunkSize:= Socket.ReceiveLength;
      ChunkSize:= CliSocket.RcvdCount;
      If ChunkSize > MaxChunkSize then ChunkSize:= MaxChunkSize;
//      BytesReceived:= Socket.ReceiveBuf(CopyBuffer,ChunkSize);
      BytesReceived:= CliSocket.Receive(@CopyBuffer,ChunkSize);
      Stream.Write(CopyBuffer, BytesReceived); { ...write chunk }
      Dec(FSize,BytesReceived);
      UpdateProgressBar;
    End;
    //This is called "to Syncronize trasnsmissions"
//    Socket.SendText('Send next');
    CliSocket.SendStr('Send next');
    If FSize=0 then
    begin
//      Socket.SendText('Done');
      CliSocket.SendStr('Done');
      Stream.Position:= 0;
      Image1.Picture.Bitmap.LoadFromStream(Stream);
      FSize:= 0;
      ProgressBar.Position:= 0;
      Stream.Clear;
    End;
    Receiving:= False;
  End;
end;


//procedure TForm1.ClientSocket1Disconnect(Sender: TObject;
//  Socket: TCustomWinSocket);
procedure TForm1.CliSocketSessionClosed(Sender: TObject; Error: Word);
begin
  Label1.Caption:= 'Disconnected';
end;

end.

Regards,
Williams
0
 
LVL 3

Expert Comment

by:williams2
Comment Utility
..By the way. Please remove the line:

    WSocket1: TWSocket;

in the beginning at the Client app. It is never to be used, and will just cause you an error compiling it!

Regards,
Williams
0
 

Author Comment

by:ItsMe
Comment Utility
Hi williams2,
I've compiled your program (I'd to remove the WSocket1: TWSocket;  in the Server part, too).
Must I change some vars ? The program doesn't work. I'm using a peer to peer Win95 TCP/IP
Network. I wanted to use the software for 13 clients and 1 Server together in our Novell Network.
I guess that isn't possible ? Is there a possibility that all 13 PC's receive the Screen of the Server
at the same time and to do this in near real time (1-2 sec. delay is ok) ? I think taht must be possible
with UDP Protocol ?
0
 
LVL 3

Expert Comment

by:williams2
Comment Utility
This sounds very weird!!! ..I have tried this on a Novell network, and it sure did work.

I might have some solutions to your problem.

1. Have you tried out both the client and server running on the same machine? (local
2. You should change the clients IP-address to the address of the server machine.
3. Are you sure the TCP/IP protocols is both setup on both server and clients?
4. I could try to send you an example of my compilations, then you should go try them and report to me if any of those didn't work?

Regards,
Williams
0
 

Author Comment

by:ItsMe
Comment Utility
Hi Williams,
now your program is working very fine. I made a mistake with the IP Adress. This was the first step.
I need a software for presentating the screen of one PC on ALL other PC's of the LAN. The client must
work automatically. I thought of using the UDP protocol. This makes possible to send the picture to all
PC's at once. If one PC doesn't get it, the pciture will be shown wrong but this doesn't matter --- when this
doesn't happen to often. Is there another way to solve this problem ? Or do you know how to solve it ?

On all PC's of the LAN (12 PC's (clients)) the picture of the server must be shown in a interval of 1-2 seconds.

The only :-) problem is to transmit this silly picture to all PC's at the same time.
0
 
LVL 3

Expert Comment

by:williams2
Comment Utility
Hi ItsMe, I have been working a little with UDP (User Datagram Protocol) I never got it to work. I was able to send the UDP packets, but never to catch them again, have you any knowledge to some working UDP components?

Regards,
Williams
0
 

Author Comment

by:ItsMe
Comment Utility
That's my problem. I know nothing about it and I don't know how to solve my problem with TCP/IP.
0
 
LVL 3

Expert Comment

by:williams2
Comment Utility
I'm sorry, then I cannot help you at the time beeing. I will not wait until I have build YOUR project, in my oppinion, I answered your question. Go ask another question about how to use UDP, because you cannot expect me to solve your problem without your help. You can now choose 3 things:

1. Reject the answer, you are just wasting my time.
2. Leave a comment on where you have found some components that suits your current Delphi installation and project.
3. Give the credits, and go ask another question about UDP and how to solve it. I'll be there to support your project.

Regards,
Williams
0
 

Author Comment

by:ItsMe
Comment Utility
I will ask a new question but you were very helpful for me because I can use your code in a part, too.
Regards
ItsMe

PS: The new qestion Subject is "Screen-presentating software"
0
 

Author Comment

by:ItsMe
Comment Utility
I gave this question 100 points not ten ! What's that ???
0
 
LVL 3

Expert Comment

by:williams2
Comment Utility
That's the value of the question, if another user comes here to seek an answer to his/her question.

I'll be there ItsMe, I hope I didn't offend you, I just did use more that 2 days solving your problem. :-))

Regards,
Williams
0

Featured Post

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

Suggested Solutions

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

6 Experts available now in Live!

Get 1:1 Help Now