Solved

File transfer over sockets?

Posted on 2000-05-13
9
231 Views
Last Modified: 2010-04-04
What are other good ways of sending a file across sockets by not using SendStream and not loading a whole filestream into a pointer and sending it? (im not using TClientSocket, im using WSOcket)

--Olympus
0
Comment
Question by:Olympus
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 4
9 Comments
 

Author Comment

by:Olympus
ID: 2807691
Adjusted points from 3 to 50
0
 
LVL 3

Expert Comment

by:bryan7
ID: 2807783
code from williams2 to send the screen..
just replace TMemoryStream for TFileStream



                         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.
0
 

Author Comment

by:Olympus
ID: 2807795
this is a rather rudimentary method, i want something simple but effective like this:
var
P: Pointer;
FS: TFileStream;
begin
FS := TFileStream.Create('c:\windows\calc.exe', fmOpenRead or fmShareDenyNone);
GetMem(P, FS.Size);
FS.Read(P, FS.Size);
WSocket1.Send(P, SizeOf(P));
FreeMem(P);
FS.Free;
end;

but inwhich the server does not load the whole file into memory (500 megs?)
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 3

Expert Comment

by:bryan7
ID: 2809101
you can't send more than 8kb at a time..
and using TFileStream with the demo I posted .. it doesn't load the complete file then 8kb each time..

I'm sorry.. I'm almost 100% sure you can't send the file at once.. 8kb at a time ..
0
 

Author Comment

by:Olympus
ID: 2809142
no that code works, i just want some code that doesnt load the whole thing into memory.
tell me, would something like this work:

var
  fs: TFileStream;
  p: Pointer;
begin
  fs:=TFileStream.Create('c:\config.sys', fmOpenRead);
  GetMem(p, 8192);
  while fs.Position < fs.Size do
  begin
    fs.Read(p, 8192);
    WSocket1.Send(p, SizeOf(p));
  end;
  fs.Free;
end;

from what ive read that would screw it up right?
i need something like that, in one function thats sends a file without loading it into memory all at once like my previous example...
0
 
LVL 3

Expert Comment

by:bryan7
ID: 2809953
using that.. I think the buffer would be overloaded.. I don't know..
did you try ?
0
 

Author Comment

by:Olympus
ID: 2824039
that doesnt work...
0
 
LVL 3

Accepted Solution

by:
bryan7 earned 50 total points
ID: 2824295
what doesn't work ?
0
 

Author Comment

by:Olympus
ID: 2861034
Comment accepted as answer
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Michael from AdRem Software explains how to view the most utilized and worst performing nodes in your network, by accessing the Top Charts view in NetCrunch network monitor (https://www.adremsoft.com/). Top Charts is a view in which you can set seve…
Sometimes it takes a new vantage point, apart from our everyday security practices, to truly see our Active Directory (AD) vulnerabilities. We get used to implementing the same techniques and checking the same areas for a breach. This pattern can re…
Suggested Courses
Course of the Month8 days, 11 hours left to enroll

615 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