Solved

help with BlockRead BlockWrite ScktComp

Posted on 2009-07-07
3
576 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
ID: 24800382
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
ID: 24801640
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
ID: 24805470
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

Networking for the Cloud Era

Join Microsoft and Riverbed for a discussion and demonstration of enhancements to SteelConnect:
-One-click orchestration and cloud connectivity in Azure environments
-Tight integration of SD-WAN and WAN optimization capabilities
-Scalability and resiliency equal to a data center

Question has a verified solution.

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

Suggested Solutions

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
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…
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …
In a recent question (https://www.experts-exchange.com/questions/29004105/Run-AutoHotkey-script-directly-from-Notepad.html) here at Experts Exchange, a member asked how to run an AutoHotkey script (.AHK) directly from Notepad++ (aka NPP). This video…

830 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