Olympus
asked on
File transfer over sockets?
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
--Olympus
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(Se nder: 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.SrvSocketSessionAva ilable(Sen der: 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.ServerSocket1Client Read(Sende r: 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(S ize));
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.Positio n;
If ChunkSize>0 then
begin
If ChunkSize > MaxChunkSize then ChunkSize:= MaxChunkSize;
Stream.Read(CopyBuffer,Chu nkSize);
Socket.Send(@CopyBuffer,Ch unkSize);
// 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(Sende r: TObject;
Socket: TCustomWinSocket);
procedure ClientSocket1Error(Sender: TObject; Socket: TCustomWinSocket;
ErrorEvent: TErrorEvent; var ErrorCode: Integer);
procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
procedure ClientSocket1Disconnect(Se nder: TObject;
Socket: TCustomWinSocket);}
procedure CliSocketSessionConnected( Sender: TObject; Error: Word);
procedure CliSocketSessionClosed(Sen der: TObject; Error: Word);
procedure CliSocketDataAvailable(Sen der: 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.ClientSocket1Connec t(Sender: TObject;
// Socket: TCustomWinSocket);
procedure TForm1.CliSocketSessionCon nected(Sen der: 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(Send er: 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.SendT ext('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,2 5);
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(S ender: TObject;
// Socket: TCustomWinSocket);
procedure TForm1.CliSocketDataAvaila ble(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>=Size Of(TempSiz e) then
If CliSocket.RcvdCount>=SizeO f(TempSize ) then
begin
// Socket.ReceiveBuf(TempSize ,SizeOf(Te mpSize)); //get the size
CliSocket.Receive(@TempSiz e,SizeOf(T empSize));
// Socket.ReceiveBuf(TempSize ,SizeOf(Te mpSize)); //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(CopyBuff er,ChunkSi ze);
BytesReceived:= CliSocket.Receive(@CopyBuf fer,ChunkS ize);
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.Load FromStream (Stream);
FSize:= 0;
ProgressBar.Position:= 0;
Stream.Clear;
End;
Receiving:= False;
End;
end;
//procedure TForm1.ClientSocket1Discon nect(Sende r: TObject;
// Socket: TCustomWinSocket);
procedure TForm1.CliSocketSessionClo sed(Sender : TObject; Error: Word);
begin
Label1.Caption:= 'Disconnected';
end;
end.
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(Se
// Socket: TCustomWinSocket);
procedure SrvSocketSessionAvailable(
procedure SocketDataAvailable(Sender
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:
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.SrvSocketSessionAva
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
//procedure TForm1.ServerSocket1Client
// 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
Socket.Send(@Size,SizeOf(S
End;
//procedure TForm1.SendNextPart(Socket
procedure TForm1.SendNextPart(Socket
const
MaxChunkSize = 8192; { copy in 8K chunks }
var
ChunkSize: Integer;
CopyBuffer: Array[0..MaxChunkSize] of Byte;
Begin
Chunksize:= Stream.Size-Stream.Positio
If ChunkSize>0 then
begin
If ChunkSize > MaxChunkSize then ChunkSize:= MaxChunkSize;
Stream.Read(CopyBuffer,Chu
Socket.Send(@CopyBuffer,Ch
// Socket.SendBuf(CopyBuffer,
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(Sende
Socket: TCustomWinSocket);
procedure ClientSocket1Error(Sender:
ErrorEvent: TErrorEvent; var ErrorCode: Integer);
procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
procedure ClientSocket1Disconnect(Se
Socket: TCustomWinSocket);}
procedure CliSocketSessionConnected(
procedure CliSocketSessionClosed(Sen
procedure CliSocketDataAvailable(Sen
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
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.ClientSocket1Connec
// Socket: TCustomWinSocket);
procedure TForm1.CliSocketSessionCon
begin
Label1.Caption:= 'Connected';
Receiving:= False;
FSize:= 0;
end;
//procedure TForm1.ClientSocket1Error(
// Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
// var ErrorCode: Integer);
procedure TForm1.CliSocketError(Send
begin
ShowMessage('Did you startup the server? I cannot find it!');
end;
procedure TForm1.Button2Click(Sender
begin
// if ClientSocket1.Active then
// ClientSocket1.Socket.SendT
CliSocket.SendStr('Get me the screen');
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Label1:= TLabel.Create(Self);
Label1.SetBounds(32,72,32,
Label1.Parent:= Self;
Label1.Caption:= 'Idle..';
Button1:= TButton.Create(Self);
Button1.SetBounds(8,8,75,2
Button1.Parent:= Self;
Button1.Caption:= 'Connect';
Button1.OnClick:= Button1Click;
Button2:= TButton.Create(Self);
Button2.SetBounds(8,40,75,
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(S
// Socket: TCustomWinSocket);
procedure TForm1.CliSocketDataAvaila
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>=Size
If CliSocket.RcvdCount>=SizeO
begin
// Socket.ReceiveBuf(TempSize
CliSocket.Receive(@TempSiz
// Socket.ReceiveBuf(TempSize
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(CopyBuff
BytesReceived:= CliSocket.Receive(@CopyBuf
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.Load
FSize:= 0;
ProgressBar.Position:= 0;
Stream.Clear;
End;
Receiving:= False;
End;
end;
//procedure TForm1.ClientSocket1Discon
// Socket: TCustomWinSocket);
procedure TForm1.CliSocketSessionClo
begin
Label1.Caption:= 'Disconnected';
end;
end.
ASKER
this is a rather rudimentary method, i want something simple but effective like this:
var
P: Pointer;
FS: TFileStream;
begin
FS := TFileStream.Create('c:\win dows\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?)
var
P: Pointer;
FS: TFileStream;
begin
FS := TFileStream.Create('c:\win
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?)
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 ..
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 ..
ASKER
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.sy s', 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...
tell me, would something like this work:
var
fs: TFileStream;
p: Pointer;
begin
fs:=TFileStream.Create('c:
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...
using that.. I think the buffer would be overloaded.. I don't know..
did you try ?
did you try ?
ASKER
that doesnt work...
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Comment accepted as answer
ASKER