Link to home
Start Free TrialLog in
Avatar of joepezt
joepezt

asked on

trivia FTP using ICS

hi!

is there any easy way to transfer files by using Twsocket (ICS), i am NOT Talking about the ftp component!, and i am not interrested in indy.

how to do this by sending a stream to the destination

thanx
ASKER CERTIFIED SOLUTION
Avatar of rondi
rondi

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of rondi
rondi

Sorry, ignore the line
  fname := TEMP_DIR + '\' + fi.Name;

Also note that this is a very simple example where
a client makes a new connection to send a single file.
The server is not threaded and so processes each client in turn.

rondi.
Avatar of joepezt

ASKER

ok, but does remotehost knows the filesize?. and is it easy writing a resume request =?
Are you writing the remote host program ?
Avatar of joepezt

ASKER

no, i am trying to make a trivia file transfer, like DCC on IRC

and the method used is random listening port, and 1 connection
the next connection shouyld have another random port (preferably  the next available)

Shoulda said so from the get-go.
Sorry, I can't help - don't know a hellova lot about
IRC specs or DCC (whatever that is).

I suggest you look at some of the tech. specs for IRC.

rondi.
Avatar of joepezt

ASKER

DCC is not that different, i think you can help me anyway, cause DCC is just an open data socket and as soon as it is connected, it will send  the data, like Trivia FTP, or FTP-Data.

i just need to know how to send and resume..

thanks :)
Avatar of joepezt

ASKER

hi!, i have tested your sample, but this seems to be very memory consuming :

how can i just allocate small portions of memory and send it ?

stian ..


unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    clisocket: TWSocket;
    srvsocket: TWSocket;
    Memo1: TMemo;
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
  procedure SrvSocketSessionAvailable(Sender: TObject; Error: Word);
    procedure Button1Click(Sender: TObject);
    procedure clisocketDataAvailable(Sender: TObject; Error: Word);
    procedure clisocketSessionConnected(Sender: TObject; Error: Word);
  private
    { Private declarations }
  public
  fileSize : integer;
  ms: TMemoryStream;
  ms2 : TMemoryStream;
  Procedure SendFile;
end;

var
  Form1: TForm1;


implementation

{$R *.DFM}



procedure TForm1.SrvSocketSessionAvailable(Sender: TObject; Error: Word);
begin
 srvsocket.HSocket := SrvSocket.Accept;
end;


Procedure Tform1.SendFile;
begin
   if CliSocket.State <> wsConnected then
   begin
     CliSocket.Proto := 'tcp';
     CliSocket.Port  := '60';
     CliSocket.Addr  := '127.0.0.1';
     CliSocket.Connect;
   end;
end;


procedure TForm1.FormCreate(Sender: TObject);
begin
 srvsocket.Listen;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 ms := TMemoryStream.Create;
sendfile;
end;

procedure TForm1.clisocketDataAvailable(Sender: TObject; Error: Word);
var
 buf: array [0..65535] of byte;
 recd, totalrecd: integer;
begin
 recd := -1;
 while recd <= 0 do
 begin
   Application.ProcessMessages;
   if Application.Terminated then exit;
   recd := srvsocket.Receive(@buf[0],filesize);
 end;
 totalrecd := 0;
 while totalrecd < fileSize do
 begin
   Application.ProcessMessages;
   if Application.Terminated then exit;
   try
     recd := srvsocket.Receive(@buf[0],SizeOf(buf));
   except
     recd := 0;
   end;
   if recd <= 0 then
     break
   else
   begin
     ms.Write(buf[0],recd);
     totalrecd := totalrecd + recd;
   end;
 end;
 ms.SaveToFile('d:\test\test.mp3');
 srvsocket.Close;
 ms.Free;
 ms2.free;
end;

procedure TForm1.clisocketSessionConnected(Sender: TObject; Error: Word);
begin
     ms2 := TMemoryStream.Create;
     ms2.LoadFromFile('g:\tysk\Lautsprecher - Richtig Laut (Mario Lopez Remix).mp3');
     filesize := ms2.Size;
     CliSocket.Send(ms2.Memory,ms2.Size);
     CliSocket.Close;
end;

end.



Hadn't realized you were workin with mp3s!
Well, the best way to reduce mem. consumption would be to
not use memstream.LoadFromFile; instead, read blocks of data from the file and store in a buffer array. check out the BlockRead/BlockWrite functions. Do away with the memory streams and try this:

type
  T16Kb = 0..16383;
  T32Kb = 0..32767;
  T64Kb = 0..65535;
  T128Kb = 0..131071;

procedure TForm1.clisocketSessionConnected(Sender: TObject; Error: Word);
var
  f: file;
  buf: array[T64Kb] of byte;
  bread: integer;
begin
  try
    AssignFile(f,'g:\tysk\Lautsprecher - Richtig Laut (Mario Lopez Remix).mp3');
    Reset(f);
    filesize := System.FileSize(f); //i THINK it's the System unit
    while not EOF(f) do
    begin
      BlockRead(f,buf[0],SizeOf(buf),bread); //pls check my syntax here
      //add any progress bar code here eg. prgbar.position := prgbar.position + Round((bread/filesize)*100)
      CliSocket.Send(@buf[0],bread);
    end;    
    CliSocket.Close;
    CloseFile(f);
  except
    CliSocket.Close;
    MessageDlg('Failed to send file',mtError,[mbOk],0);
  end;
end;

//---------------------------------------

procedure TForm1.clisocketDataAvailable(Sender: TObject; Error: Word);
var
  buf: array [T64Kb] of byte;
  recd, totalrecd, numwrote: integer;
  f: file;
begin
try
  recd := -1;
  while recd <= 0 do
  begin
    Application.ProcessMessages;
    if Application.Terminated then exit;
    recd := srvsocket.Receive(@buf[0],filesize);
  end;
  totalrecd := 0;
  AssignFile(f,'d:\test\test.mp3');
  Rewrite(f);
  while totalrecd < fileSize do
  begin
    Application.ProcessMessages;
    if Application.Terminated then exit;
    try
      recd := srvsocket.Receive(@buf[0],SizeOf(buf));
    except
      recd := 0;
    end;
    if recd <= 0 then
      break
    else
    begin
      BlockWrite(f,buf[0],recd,numwrote); //dbl check this line
      if numwrote < recd then
        raise Exception.Create('Error writing to file')
      else
        totalrecd := totalrecd + recd;
    end;
  end;
  srvsocket.Close;
  CloseFile(f);
except
  on E:Exception do
    MessageDlg(E.Message,mtError,[mbok],0);
  try
    CloseFile(f);
  except
  end;  
end; //try block
end;  //procedure
Avatar of joepezt

ASKER

i get IO error 998 on this line :

BlockRead(f,buf[0],SizeOf(buf),bread);

are you sure
 buf: array[T64Kb] of byte;
is the correct?
Avatar of joepezt

ASKER

i am not just planning to send mp3's

all sorts of files...

:)
Hi Joe,
That T64Kb line's fine - you can replace it with 0..65535 if you prefer.

Try look up I/O Error 998 in the help files. Check that the file exists and there's no sharing violation or anything (like another prog. denying read access (though I doubt this))

rondi
Avatar of joepezt

ASKER

rondi, i cannot find out how to handle this error code :-(
Avatar of joepezt

ASKER

I Allmost got this one working, but never got the files 100%, i will try testing more in the future :=