views:

1118

answers:

4

Hi,

I want to meassure the throughput of a link using Windows build-in FTP tool inside a Perl script. Therefore the script creates the following command script:

open <ip>
<username>
<password>
hash
get 500k.txt
quit

Afterwards I run the command script using the following Perl code:

system(@args);
@args = ("ftp", "-s:c:\\ftp_dl.txt");
system(@args);

If I run the command inside a DOS-box the output looks like this:

ftp> open <ip>
Connected to <ip>
220 "Welcome to the fast and fabulous DUFTP005 ftp-server :-) "
User (<ip>:(none)):
331 Please specify the password.

230 Login successful.
ftp> hash
Hash mark printing On  ftp: (2048 bytes/hash mark) .
ftp> get 500k.txt
200 PORT command successful. Consider using PASV.
150 Opening BINARY mode data connection for 500k.txt (14336 bytes).
#######
226 File send OK.
ftp: 14336 bytes received in 0.00Seconds 14336000.00Kbytes/sec.
ftp> quit
221 Goodbye.

To be able to get the throughput I need the extract that line:

 ftp: 14336 bytes received in 0.00Seconds 14336000.00Kbytes/sec.

I'm not very familiar with Perl. Does anybody have an idea how to get that line?

A: 

You should try and use libcurl which is more suited for the task.

There is an easy to use API

kmkaplan
+3  A: 

Use either open in pipe mode:

open($filehandle, "$command|") or die "did not work: $! $?";
while(<$filehandle>)
{
#do something with $_
}

or use backticks:

my  @programoutput=`$command`
heeen
Wouldn't that be open($filehandle,"$command|")?
Mathieu Longtin
Note, however, that both of these only capture standard output of the command. You have to do a bit of extra work to get standard error. I don't know which ones the DOS ftp command uses though.
brian d foy
@Mathieu Longtin: correct.
heeen
`open($fh,'-|',$command)`
Brad Gilbert
+2  A: 

You can't get the output with system().

Instead use bactkicks:

my $throughput = 0;
my $output = `ftp -s:c:\\ftp_dl.txt`;
if (($? == 0) && ($output =~ /([\d+\.]+)\s*K?bytes\/sec/m)) {
    $throughput = $1;
}

$output will contain all the lines from the execution of the ftp command (but not any error message sent to STDERR).
Then we check if ftp returned success (0) and if we got a throughput somewhere in the output.
If so, we set $throughput to it.

This being Perl, there are many ways to do this:

You could also use the Net::FTP module that supports Windows to deal with the file transfer and use a timing module like Time::HiRes to time it and calculate your throughput.

This way you won't depend on the ftp program (your script would not work on localised version of Windows for instance without much re-work, and you need to rely on the ftp program to be installed and in the same location).

Renaud Bompuis
Thanks for your help. You solved my problem :)
+2  A: 

See perlfaq8, which has several answers that deal with this topic. The ones you probably need for this question are:

Also, you might be interested in some of the IPC (Interprocess Communication) Perl modules that come in the standard library:

  • IPC::Open2
  • IPC::Open3

Some of the Perl documentation might also help:

If you're not familiar with the Perl documentation, you might check out my Perl documentation documentation.

Good luck,

brian d foy