Solved

help with BlockRead BlockWrite ScktComp

Posted on 2009-07-07
3
569 Views
Last Modified: 2013-11-23
I finally finish my demo of transfer files over a network but the code dont work, someone can tell me what im doing wrong?
Client
 

unit UntMain;
 

interface
 

uses

  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

  Dialogs, ScktComp, StdCtrls, Menus;
 

type

  TForm1 = class(TForm)

    Open: TOpenDialog;

    Client: TClientSocket;

    PopupMenu1: TPopupMenu;

    SendData1: TMenuItem;

    procedure FormCreate(Sender: TObject);

    procedure SendData1Click(Sender: TObject);

  private

    { Private declarations }

  public

    { Public declarations }

  end;
 

var

  Form1: TForm1;
 

implementation
 

{$R *.dfm}
 

procedure TForm1.FormCreate(Sender: TObject);

begin

 Client.Open;

end;
 

procedure SendFile(FilePath: String; Socket: TCustomWinSocket);

var

 F: File;

 NumRead: Integer;

 Buffer: array [1..4096] of Char;

begin

 AssignFile(F, FilePath);

 Reset(F, 1) ;

 repeat

   BlockRead(F, Buffer, SizeOf(Buffer), NumRead);

   Socket.SendBuf(Buffer, NumRead);

  until (NumRead = 0);

  CloseFile(F) ;

end;
 
 

procedure TForm1.SendData1Click(Sender: TObject);

begin

 Client.Socket.SendText('FILE');

 SendFile('C:\PortScan.exe', Client.Socket);

end;
 

end.
 

|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 

Server
 

unit UntMain;
 

interface
 

uses

  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

  Dialogs, ScktComp;
 

type

  TForm1 = class(TForm)

    Server: TServerSocket;

    procedure FormCreate(Sender: TObject);

    procedure ServerClientRead(Sender: TObject; Socket: TCustomWinSocket);

  private

    { Private declarations }

  public

    { Public declarations }

  end;
 

var

  Form1: TForm1;
 

implementation
 

{$R *.dfm}
 

procedure TForm1.FormCreate(Sender: TObject);

begin

  Server.Open;

end;
 

procedure GetFile(FilePath: string; Socket: TCustomWinSocket);

var

  F: file;

  NumRead, NumWritten: Integer;

  Buffer: array[1..4096] of Char;

begin

  AssignFile(F, FilePath);

  ReWrite(F, 1);

  repeat

    Socket.RecvBuf(Buffer, NumRead);

    BlockWrite(F, Buffer, NumRead, NumWritten);

  until (NumWritten <> NumRead);

  CloseFile(F);

end;
 

procedure TForm1.ServerClientRead(Sender: TObject;

  Socket: TCustomWinSocket);

var

  Data: string;

begin

  Data := Socket.RecvText;

  if Data = 'FILE' then

  begin

    GetFile('File.exe', Socket);

  end;

end;
 

end.

Open in new window

0
Comment
Question by:CtrlShft
3 Comments
 
LVL 22

Expert Comment

by:8080_Diver
Comment Utility
In what way does the code not work?  Are there error messages?  Have you stepped through it in debug mode?
0
 
LVL 4

Accepted Solution

by:
JonasMalmsten earned 125 total points
Comment Utility
In procedure TForm1.ServerClientRead(Sender: TObject; Socket: TCustomWinSocket);

Data will contain more than simply 'FILE', it will also contain the beginning of the file you are transfering, something like 'FILEMZ' + garbage, so Data = 'FILE' may never become true.

Also, ServerClientRead will be executed multiple times, each time new data is available unless the whole file can be transmitted in one block of data which is not usually the case.

GetFile is attempting to read the whole file, but the socket will not provide more data unless you call Application.ProcessMessages somewhere. You can probably get away with doing this in the loop there, but doing so will cause ServerClientRead to execute again, so you will then need to prevent this function to be re-entrant.

A better solution can be found here:
http://www.experts-exchange.com/Programming/Languages/Pascal/Delphi/Q_24530418.html
0
 

Author Comment

by:CtrlShft
Comment Utility
OK JonasMalmsten, i modified a lite bit, here is the new code:

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
 Client.Host:= 'localhost';
 Client.Port:= 1;
 Client.Open;
end;

procedure SendFile(FilePath: String);
var
 F: File;
 NumRead: Integer;
 Buffer: array [1..4096] of Char;
begin
 AssignFile(F, FilePath);
 Reset(F, 1) ;
 repeat
   Application.ProcessMessages;
   BlockRead(F, Buffer, SizeOf(Buffer), NumRead);
   Form1.Client.Socket.SendBuf(Buffer, NumRead);
  until (NumRead = 0);
  CloseFile(F) ;
end;


procedure TForm1.SendData1Click(Sender: TObject);
begin
 SendFile('C:\PortScan.exe');
end;

Server

{$R *.dfm}

procedure GetFile(FilePath: string);
var
  F: file;
  NumRead, NumWritten: Integer;
  Buffer: array[1..4096] of Char;
begin
  AssignFile(F, FilePath);
  ReWrite(F, 1);
  repeat
    Application.ProcessMessages;
    Form1.Server.Socket.RecvBuf(Buffer, NumRead);
    BlockWrite(F, Buffer, NumRead, NumWritten);
  until (NumWritten <> NumRead);
  CloseFile(F);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Server.Port:= 1;
  Server.Open;
end;

procedure TForm1.ServerClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
begin
 GetFile('File.exe');
end;

pls tell me what you think, when i send the data from the client to the server i get error "Asynchronous Socket Error 10053 "
so where i can place the GetFile procedure, because i try it on a timmer:
if Server.Socket.Connected the GetFile('File.exe');
and dont work.
0

Featured Post

Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

Join & Write a Comment

Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
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…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.

772 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

11 Experts available now in Live!

Get 1:1 Help Now