views:

105

answers:

2

Case 1

If I run below command i.e iperf in UL only, then i am able to capture the o/p in txt file

@output = readpipe("iperf.exe -u -c 127.0.0.1 -p 5001 -b 3600k -t 10 -i 1");
open FILE, ">Misplay_DL.txt" or die $!;
print FILE @output;
close FILE;

Case 2

When I run iperf in DL mode , as we know server will start listening in cont. mode like below even after getting data from client (Here i am using server and client on LAN)

@output = system("iperf.exe -u -s -p 5001 -i 1");

on server side:

D:\_IOT_SESSION_RELATED\SEEM_ELEMESNTS_AT_COMM_PORT_CONF\Tput_Related_Tools\AUTO
MATION_APP_\AUTOMATION_UTILITY>iperf.exe -u -s -p 5001
------------------------------------------------------------
Server listening on UDP port 5001
Receiving 1470 byte datagrams
UDP buffer size: 8.00 KByte (default)
------------------------------------------------------------
[1896] local 192.168.5.101 port 5001 connected with 192.168.5.101 port 4878
[ ID] Interval Transfer Bandwidth Jitter Lost/Total Datagrams
[1896] 0.0- 2.0 sec 881 KBytes 3.58 Mbits/sec 0.000 ms 0/ 614 (0%)

command prompt does not appear , process is contd...

on client side:

D:\_IOT_SESSION_RELATED\SEEM_ELEMESNTS_AT_COMM_PORT_CONF\Tput_Related_Tools\AUTO
MATION_APP_\AUTOMATION_UTILITY>iperf.exe -u -c 192.168.5.101 -p 5001 -b 3600k -t
2 -i 1
------------------------------------------------------------
Client connecting to 192.168.5.101, UDP port 5001
Sending 1470 byte datagrams
UDP buffer size: 8.00 KByte (default)
------------------------------------------------------------
[1880] local 192.168.5.101 port 4878 connected with 192.168.5.101 port 5001
[ ID] Interval Transfer Bandwidth
[1880] 0.0- 1.0 sec 441 KBytes 3.61 Mbits/sec
[1880] 1.0- 2.0 sec 439 KBytes 3.60 Mbits/sec
[1880] 0.0- 2.0 sec 881 KBytes 3.58 Mbits/sec
[1880] Server Report:
[1880] 0.0- 2.0 sec 881 KBytes 3.58 Mbits/sec 0.000 ms 0/ 614 (0%)
[1880] Sent 614 datagrams

D:\_IOT_SESSION_RELATED\SEEM_ELEMESNTS_AT_COMM_PORT_CONF\Tput_Related_Tools\AUTO
MATION_APP_\AUTOMATION_UTILITY>

so with this as server is cont. listening and never terminates so can't take output of server side to a txt file as it is going to the next command itself to create a txt file

so i adopted the alarm() function to terminate the server side (iperf.exe -u -s -p 5001) commands after it received all data from the client.

could anybody suggest me the way..

Here is my code:

#! /usr/bin/perl -w
my $command = "iperf.exe -u -s -p 5001";
my @output;
eval {
    local $SIG{ALRM} = sub { die "Timeout\n" };
    alarm 20;
    #@output = `$command`;
#my @output = readpipe("iperf.exe -u -s -p 5001");
#my @output = exec("iperf.exe -u -s -p 5001");

my @output = system("iperf.exe -u -s -p 5001");
    alarm 0;
};
if ($@) {
    warn "$command timed out.\n";
} else {
    print "$command successful. Output was:\n", @output;
}
open FILE, ">display.txt" or die $!;
print FILE @output_1;
close FILE;

i know that with system command i cannot capture the o/p to a txt file but i tried with readpipe() and exec() calls also but in vain...

could some one please take a look and let me know why the iperf.exe -u -s -p 5001 is not terminating even after the alarm call and to take the out put to a txt file

+1  A: 

Since the command might time out, you'll want to save as much output as you can while the command is running. Two ways to do this are:

  1. Save the output to a file and read the file contents after the command finishes or times out:

    my @command_output;
    eval { 
        $SIG{ALRM} = { die "timeout\n" };
        alarm(30);
        system("$command > $file");
        alarm(0);
    };
    open my $fh, '<', $file;  # error handling omitted for brevity
    @command_output = <$fh>;
    close $fh;     # oops, this said "close $file" before ... not a big deal.
    
  2. Run the command with open in -| mode and save as much output as you can while the command is running:

    my @command_output = ();
    eval {
        $SIG{ALRM} = { ... };
        alarm(30);
        open my $process, "$command |"; # or open my $process, '-|', $command
        while (<$process>) {
            push @command_output, $_;
        }
        close $process;
        alarm(0);
    };
    

In for a penny, in for a pound.

After figuring out what iperf.exe was and downloading it, I got this script to "work":

use strict;
use warnings;
my $command = "C:/cygwin/usr/local/bin/iperf.exe -u -s -p 25005";
my $file = "abc6.txt";
my ($pid,@command_output);
eval {
    my $process;
    $SIG{ALRM} = sub { 
      kill 'INT', $pid;
      close $process;
      die "timeout\n" 
    };
    alarm(10);
    $pid = open $process, "$command |";
    while (<$process>) {
      push @command_output, $_;
    }
    close $process;
    alarm(0);
};
print "eval block result was: $@\n";
print "Output was:\n------\n",@command_output;

I strongly urge you to familiarize yourself with all of the functions and syntax of this code before you try to get too much use out of it.

mobrule
i tried, but either way did not work at allIst way::my @command_output;eval { $file = "dummy.txt"; $command = "iperf.exe -u -s -p 5001"; $SIG{ALRM} = { die "timeout\n" }; alarm 30; system("$command > $file"); alarm 0;};if ($@) { #print"$@\n"; warn "$command timed out.\n";} else { print "$command successful. Output was:\n", @output;}open my $fh, '<', $file; # error handling omitted for brevity@command_output = <$fh>;print $fh @command_output;close $file;i got o/p => iperf.exe -u -s -p 5001 timed out.
second way::no o/p at all#! /usr/bin/perl -wmy $command = readpipe("iperf.exe -u -s -p 5001");my @output;eval {local $SIG{ALRM} = sub { die "Timeout\n" }; alarm 10; #my @output = `iperf.exe -u -s -p 5001`; #my @output = readpipe("iperf.exe -u -c 192.168.5.101 -p 5001 -b 3600k -t 5");open my $process, "$command |"; # or open my $process, '-|', $command while (<$process>) {push @output, $_;}alarm 0;open FILE, ">display.txt" or die $!;print FILE @output;close FILE;};if ($@) {#print"$@\n";warn "$command timed out.\n";} else {print "$command successful. Output was:\n", @output;}
@rockyurock: are you using both `@command_output` and `@output`? You should use one or the other but not both. I omitted `use strict; use warnings;` from my examples for brevity, but maybe I should put them in.
mobrule
@rockyurock Re 1st comment: Don't say `print $fh @command_output`. `$fh` is an input filehandle. If you want to print to your screen just say `print @command_output`
mobrule
@rockyurock Re 2nd comment: It looks you are writing to the file `display.txt` inside the `eval` block? If the command times out you will exit from the block and that code won't get executed. Move it outside the `eval` block.
mobrule
@rockyurock Re 2nd comment: I expect `$command` to contain `"iperf.exe -u -s -p 5001"`. By making it the return value of `readpipe`, you are setting `$command` to the **output** of `"iperf.exe ..."`! (In which case, you can just `print $command`).
mobrule
How can you say that it is working ??i tried your porgram as such on windows and the cursor is always blinking and did not get any output generated.however when i replaced the command my $command = "iperf.exe -u -s -p 25005";with system(); linke my $command = "system(iperf.exe -u -s -p 25005");i could see the output on terminal but again the process never terminated and no o/p generated at all/rocky...
@rockyurock Please read up on Perl's `system` function (see http://search.cpan.org/perldoc/perlfunc#system_LIST__ , for example). The return value is **not** the output of the command. When you call `system` outside the `eval` block, the command is running and is not subject to the alarm.
mobrule
A: 

@mobrule
Finally i am able to achieve what i wanted, below is code used, but now it is giving me also an error on each subsequent Runs...

Error Message::

The process cannot access the file because it is being used by another process.iperf.exe -u -s -p 5001 successful. Output was:

code::

my @command_output; eval { my $file = "abc6.txt";
$command = "iperf.exe -u -s -p 5001"; alarm 10; system("$command > $file"); alarm 0; close $file; }; if ($@) { warn "$command timed out.\n"; } else { print "$command successful. Output was:\n", $file; } unlink $file;

Output::

abc6.txt

Server listening on UDP port 5001 Receiving 1470 byte datagrams

UDP buffer size: 8.00 KByte (default)

[1892] local 192.168.5.101 port 5001 connected with 192.168.5.101 port 3553 [ ID] Interval Transfer Bandwidth Jitter Lost/Total Datagrams [1892] 0.0- 2.0 sec 881 KBytes 3.61 Mbits/sec 0.000 ms 0/ 614 (0%)

also when for each run of this "iperf.exe" the process always remains live in Taskmanager, if i kill it manually before each Run OR changing the file for taking o/p every time, then i am able to run it successfully one after another

could you please suggest how can i kill that process rather than doing it manually from taskmanager and get rid of that problem

i tried to unlink the file used but that did not solve the purpose thank rocky..